253 Commits
Author SHA1 Message Date
ptitSeb 3c98cbccbe Bumped to v0.1.8 2020-12-16 07:58:23 +01:00
ptitSeb 3a5c6751e2 Many fixes to Double->Int x87 opcodes ([DYNAREC] too) 2020-12-15 15:53:38 +01:00
ptitSeb 002d3d7b9b This also fixes 66 D9 and 66 DD opcodes 2020-12-15 15:52:53 +01:00
ptitSeb e57a66da04 [DYNAREC] Fixed AAD opcode 2020-12-15 15:51:13 +01:00
ptitSeb b1ecad2d49 Fixed 66 D9 and 66 DD opcodes 2020-12-15 15:50:18 +01:00
ptitSeb 658a107f60 Better log for FE xx and FF xx Illegal Instructions on interpretor 2020-12-15 15:49:39 +01:00
ptitSeb 7b419ce5f1 Fix a callback for pulse audio (help #268, seems to be working now) 2020-12-15 15:40:58 +01:00
ptitSeb 367df08989 Fix Zoom hack for libturbojpeg.so (for #268) 2020-12-15 07:59:04 +01:00
ptitSeb 2004006a9d Added Zoom detection and hack to first try to use system libturbojpeg.so if loaded (still for #268) 2020-12-14 21:45:57 +01:00
ptitSeb bed0f24f2b Wrapped libturbojpeg.so.0 with a small set of functions (should help #268) 2020-12-14 20:48:56 +01:00
ptitSeb 7995dfc70a Fixed a potential SIGBUS on DF /7 FISTP opcode 2020-12-14 14:12:43 +01:00
ptitSeb b29d569f6b Reworked libpulse wrappers (should be more stable and little tad faster) 2020-12-14 12:22:39 +01:00
ptitSeb 3c166c438a [DYNAREC] Added BOX86_DYNAREC_SAFEMMAP (can be usefull to speedup Wine progs, but may also introduce crash) 2020-12-13 20:25:55 +01:00
ptitSeb 03dac0ef6a [DYNAREC] Use a table read that is not thread safe in linker (I don't think thread safe is a must-have in this case) 2020-12-13 19:26:31 +01:00
ptitSeb 27cb5219ae [DYNAREC] Various simplifications 2020-12-13 19:24:27 +01:00
ptitSeb 97a7459f5d [DYNAREC] Small optims 2020-12-13 16:12:17 +01:00
ptitSeb 1eac337e59 [DYNAREC] Don't flush dynarec_log 2020-12-13 16:11:59 +01:00
ptitSeb 1613358927 [DYNAREC] Fixed a type is FS: Cache handling (should give back some speed on Wine stuff) 2020-12-13 15:38:32 +01:00
ptitSeb 2f0da26f14 [DYNAREC] Presize dblists 2020-12-13 14:21:05 +01:00
ptitSeb 45fa32cb9d [DYNAREC] Small fixes for cancelled dynablock 2020-12-13 14:19:56 +01:00
ptitSeb 9e9f2a37be [DYNAREC] Precalc exact instsize array size 2020-12-13 14:19:04 +01:00
ptitSeb 7b37bb6825 [DYNAREC] simplify this structure 2020-12-13 14:18:36 +01:00
ptitSeb 081378a178 Added empty wrapped libnsl.so 2020-12-13 10:05:28 +01:00
ptitSeb ff72343429 [DYNAREC] Removed a debug leftover 2020-12-13 10:04:57 +01:00
ptitSeb b0b8a2ca1c Fixed a warning 2020-12-13 09:09:35 +01:00
ptitSeb 55be6835b8 Removed a debug leftover (should help #227 and box-compatibility-list/#46) 2020-12-13 08:38:43 +01:00
ptitSeb c465e1de21 [VULKAN] fixed SDL2 wrapping of SDL_Vulkan_GetVkGetInstanceProcAddr 2020-12-12 19:50:04 +01:00
ptitSeb 0f255de201 Made box86context_t lighter for easier debugging (also reorganised member order) 2020-12-12 19:50:04 +01:00
ptitSeb deb04610b5 Revert commit 31a108b685, previous method seems better 2020-12-12 19:25:53 +01:00
ptitSeb a9887fe471 Fixed an old type on Bridge handling 2020-12-12 17:09:35 +01:00
ptitSeb 4b3c5a7f6f [DYNAREC] Reworked Dynablock memory manager 2020-12-12 15:24:05 +01:00
ptitSeb 0058d3563d Added 66 F0 0F B1 opcode 2020-12-12 10:18:13 +01:00
ptitSeb 52a4808f2c Added a few more function to wrapped libfontconfig 2020-12-12 10:09:17 +01:00
ptitSeb 7a0874165f Added 1 wrapped function to libfontconfig 2020-12-12 09:37:44 +01:00
ptitSeb 7c7acd134b Small wrapped libmpg123 and pulse change 2020-12-11 22:27:43 +01:00
ptitSeb ddd4874baa [DYNAREC] Some small optim on support function for the Dynarec 2020-12-11 21:04:11 +01:00
ptitSeb 23f91b1a0d [DYNAREC] All Interpretor to switch back to Dynarec on more opcodes 2020-12-11 20:47:23 +01:00
ptitSeb b8c32d580b [DYNAREC] If a block wasn't created because executable memory was not allocated, delete the whole dynablocks to try again later 2020-12-11 20:35:39 +01:00
ptitSeb c0e67004d5 [DYNAREC] Reworked the dynarec signal handling, to improve its performances 2020-12-11 20:25:24 +01:00
ptitSeb 38a557b7e9 [DYNAREC] Don't try to create 0 sized Map block 2020-12-11 17:28:32 +01:00
ptitSeb 7d6d5d673d [DYNAREC] added 64 A2 opcode 2020-12-11 17:27:23 +01:00
ptitSeb 2cf067f004 [DYNAREC] Don't try to a free a 0 sized of NULL pos Map 2020-12-11 17:27:08 +01:00
ptitSeb 92d9bc525f [DYNAREC] Try to avoid some deadlock with dynarec that could happens in some specific cases involving signals 2020-12-11 16:43:25 +01:00
ptitSeb dca91b1efc added 64 A0 opcode ([DYNAREC] too) 2020-12-11 16:32:14 +01:00
ptitSeb 6bf1ea7539 [DYNAREC] Remove some old code behind ifdefs 2020-12-11 14:23:18 +01:00
ptitSeb 670b13595b Improved the PltRelocator detection of elfloader 2020-12-10 17:14:17 +01:00
ptitSeb dcbb8b29de Added some X11 wrapped functions 2020-12-10 17:12:40 +01:00
ptitSeb 7284c817b2 And more libxcb* wrapped functions 2020-12-10 17:05:54 +01:00
ptitSeb b16912132f Added some xcb_xrandr wrapped functions 2020-12-10 15:44:53 +01:00
ptitSeb 9805ad7f3a Initialize context as soon as possible in library (should help #265 and #266) 2020-12-10 15:11:26 +01:00
ptitSeb 4e7e0f6aab Added a few libdrm wrapped function 2020-12-10 13:56:24 +01:00
ptitSeb c905ebfdd2 Added wrapped libSDL2_ttf-2.0.so.0 (copy if the sdl1 version) 2020-12-10 13:51:31 +01:00
ptitSeb b5c787938c Fixed commented code, in case it gets uncommented someday 2020-12-10 13:38:59 +01:00
ptitSeb 69ca5351b4 Added a bunch of wrapped xcb* functions 2020-12-10 12:35:52 +01:00
ptitSeb 3f42372603 Added liblcms2 wrapped lib (partial wrapping, just enough for wine) 2020-12-09 15:54:33 +01:00
ptitSeb 595028e9ec Reworked Exit, to avoid segfault and lockup and end of execution 2020-12-09 11:25:14 +01:00
ptitSeb 7358a049ef Huge refactoring (again), completly removed old Callback mecanism (working to have only 1 x86emu_t structure per thread, almost there) 2020-12-08 22:38:51 +01:00
ptitSeb 792aeda72e Be more smart to when to apply PltRelacator or not (fix SuperHexagon's libGLEW loading) 2020-12-08 21:44:21 +01:00
ptitSeb 53bf2d277b Added wrapped libldap_r and liblber 2020-12-08 08:10:02 +01:00
ptitSeb 0cbc55ba24 Fix potential build error on old system (at least with old headers) 2020-12-08 07:56:18 +01:00
ptitSeb 7b0d228972 Added a few XTandr wrapped functions 2020-12-08 07:54:40 +01:00
ptitSeb 8ac0b66836 Improved Segment offset Cache, and enable GS: caching (some speed boost on Linux apps) 2020-12-07 13:56:29 +01:00
ptitSeb 2756b1b9dd [DYNAREC] fixed some warning and a typo from last commit 2020-12-06 22:31:15 +01:00
ptitSeb e3f44bae26 [DYNAREC] Huge refactor to simplify Dynablock handling 2020-12-06 21:52:27 +01:00
ptitSeb 1963589186 Mooore Thread Cancel slots 2020-12-06 21:14:38 +01:00
ptitSeb a5c9675b84 [DYNAREC] Removed Mark mecanism (it needs mutex to run properly, so it's too heavy) 2020-12-06 15:13:40 +01:00
ptitSeb 76747d5c38 [DYNAREC] Immprove log for SMC debugging option 2020-12-06 15:12:36 +01:00
ptitSeb 59bfeb9fb2 [DYNAREC] This barrier optimization seems to break Mono on Linux, so reverting it for now 2020-12-06 13:15:09 +01:00
ptitSeb c40669b429 [DYNAREC] Optimized AddMark function to not redo what is already done 2020-12-05 23:22:09 +01:00
ptitSeb d83cdbfeeb Fixed a potential segfault 2020-12-05 23:21:29 +01:00
ptitSeb d8773e96d6 Not sure if awesomium_process needs or not emulated libpng12. Commenting for now 2020-12-05 20:59:24 +01:00
ptitSeb 78571698c2 Some improvements in wrapped libpng handling 2020-12-05 19:43:52 +01:00
ptitSeb 77282f1ff1 Added one more wrapped function to libglib2 2020-12-05 17:07:57 +01:00
ptitSeb 953fcb7f1b Fixed handling of TLS object with a 0 offset (help Garry's Mod, probably a few other too) 2020-12-05 16:59:08 +01:00
ptitSeb 1905e4a7f6 Better handling of libtcmalloc_minimum.so.4 2020-12-05 16:15:35 +01:00
ptitSeb 31e6ae0705 Improved the BOX86_NOBANNER behaviour 2020-12-05 12:49:17 +01:00
ptitSeb 31a108b685 Change method used for Thread Cancel registeration 2020-12-04 21:47:39 +01:00
ptitSeb b122c68b16 Improved a bit XImage handling 2020-12-04 21:47:04 +01:00
ptitSeb 0efae1fdf5 Added BOX86_NOGTK to disable use of wrapped gtk libs (can be used with Steam) 2020-12-04 19:52:10 +01:00
ptitSeb 0850180861 Fixed and improved wrapped libdbus-1 2020-12-04 19:49:25 +01:00
ptitSeb 528478b379 Improved a bit wrapped libusb-1 2020-12-04 17:55:30 +01:00
ptitSeb 65302010db Small remork on cancel tread registration mecanism (should fix memory leaks) 2020-12-03 12:01:07 +01:00
ptitSeb 6b32440347 Small fix (mostly cosmetic) in a pthread wrapped function signature 2020-12-03 12:00:32 +01:00
ptitSeb 5a0b6c419e [DYNAREC] Fixed some memory leak 2020-12-03 11:59:43 +01:00
ptitSeb 94c5d0205b fixed some warning 2020-12-03 11:58:49 +01:00
ptitSeb 0f2998a672 More libxml2 wrapping improvment for wine 2020-12-02 21:39:27 +01:00
ptitSeb 1ba7936ef7 Improve wrapping of libxml2 (especially for wine msxml3.dll.so) 2020-12-02 21:16:19 +01:00
ptitSeb 5192aacb22 [RPI] Added runtime hack to get TokiTori2+ running on Pi 2020-12-01 15:13:22 +01:00
ptitSeb ac2adcaf52 A bit more logs when function name is not found 2020-12-01 15:01:12 +01:00
ptitSeb 1b3e707f62 Added SDL_LogGetOutputFunction to wrapped libsdl2 and refactored remaining callback functions 2020-12-01 08:59:01 +01:00
ptitSeb 925fc67c66 Fixed a typo in wrapped libxml2 2020-12-01 08:33:47 +01:00
ptitSeb 54ce6deb1c Wrapped libxslt (should help #259) 2020-11-30 20:02:57 +01:00
ptitSeb 754859d28a Wrapped libxml2 (should help #259) 2020-11-30 18:42:09 +01:00
ptitSeb 269bc9e289 [DYNAREC] Disable one of the new optim, it breaks some installer 2020-11-29 17:26:54 +01:00
ptitSeb 35c768c040 [DYNAREC] Fixed an issue with an optimisation that was too agressive 2020-11-29 13:51:11 +01:00
ptitSeb ff45cfed83 [DYNAREC] Various fixes on some dynarec optimisation mecanism 2020-11-28 16:07:04 +01:00
ptitSeb 38c5c1c17a [DYNAREC] Added 64 FF /2 CALL FS:Ed opcode 2020-11-28 15:32:22 +01:00
ptitSeb 423b301596 Added syscal 356 (and code to emulate it if not present) 2020-11-28 12:26:40 +01:00
ptitSeb 000c11f9ea [PANDORA] Added basic implementation of renameat2 2020-11-28 12:17:12 +01:00
ptitSeb cea4a02ad9 Fixed RPATH handling when a list of path was set 2020-11-28 11:10:01 +01:00
ptitSeb 4e9bc39381 [DYNAREC] Some rework on dynablock management 2020-11-27 17:40:16 +01:00
ptitSeb ad084da13d Start a new dev. cycle with v0.1.7 2020-11-27 10:18:13 +01:00
ptitSeb 27e5262f1d Bumped to v0.1.6 2020-11-26 09:43:33 +01:00
ptitSeb 363464092e [DYNAREC] Added 66 60/61 16bits PUSHA/POPA opcodes 2020-11-25 12:04:47 +01:00
ptitSeb b2cab70427 [DYNAREC] Improved 16bits immediate PUSH opcodes 2020-11-25 12:04:46 +01:00
ptitSeb 44d5301244 [DYNAREC] Improved 16bits PUSH/POP opcodes 2020-11-25 12:04:46 +01:00
ptitSeb 8e4f4feb3c Updated CHANGELOG 2020-11-25 12:04:46 +01:00
ptitSeb e9f6f8824c [DYNAREC] Fixed a potential SIGBUS with int64->double loading 2020-11-24 12:04:03 +01:00
ptitSeb be6f9870d0 Added 64 01/03/11/2B opcodes 2020-11-23 18:41:20 +01:00
ptitSeb bb086223c7 Update README.md 2020-11-23 13:33:36 +01:00
ptitSeb be6a3bff3f Fixed 2 wrapped functions signature in libappindicator (help Steam) 2020-11-22 20:42:49 +01:00
ptitSeb adfc5fda2e Fixed a SEGBUS on RK339 build 2020-11-22 20:31:33 +01:00
ptitSeb d833f136a0 Enable the 'GOG Linux install hack' also for RK3399 platforms 2020-11-22 18:41:37 +01:00
ptitSeb 1703e9d1b7 Refined CMakeList a bit 2020-11-22 18:41:05 +01:00
ptitSeb 011b9f93e4 [DYNAREC] Fixed 66 0F EA/EE opcodes (should fix #253 this time) 2020-11-22 17:30:30 +01:00
ptitSeb e449a4e247 Launch natively program if elf is not recognised as an i386, or not an elf 2020-11-22 14:08:11 +01:00
ptitSeb fe7f0ff842 Fixed potential BUSERROR with LOCK CMPXCHG8B opcode on interpretor 2020-11-22 13:52:44 +01:00
ptitSeb 2033e5764d Fixed potential segfault when using BOX86_LOG=2 2020-11-22 13:05:28 +01:00
ptitSeb 55175263ac [DYNAREC] Added 0F BA /5 and /7 opcodes 2020-11-22 10:52:40 +01:00
ptitSeb c484221cd6 Remove the 'suspicious segment' left over debug code 2020-11-22 10:21:55 +01:00
ptitSeb e9862cb30d [DYNAREC] Fix potential issue when multiple similar thread are launched at the same time (will help #253) 2020-11-21 20:32:52 +01:00
ptitSeb 0c7b99cbc6 [DYNAREC] Changed how opcodes 66 0F 38 08/09/0A are coded (this fixes the md5 error in #253) 2020-11-21 18:36:55 +01:00
ptitSeb 824f39e4db [DYNAREC] Potential fix for 66 0F 38 1C/1D/1E when Gx==Ex and Gx is not cached yet (help #253, but still some issues) 2020-11-21 15:31:27 +01:00
ptitSeb 66a5ce1e52 [DYNAREC] Fixed 66 0F 38 1C/1D/1E opcode (for #253, still not ok, how many opcodes are borked?) 2020-11-21 15:18:22 +01:00
ptitSeb f39637a652 [DYNAREC] Fixed 66 0F EE opcode (for #253, but still not enough) 2020-11-21 15:10:03 +01:00
ptitSeb eaf7d0a277 [DYNAREC] Fixed 66 0F 38 08/09/0A opcode (should help #253 a bit) 2020-11-21 14:54:25 +01:00
ptitSeb b61bb908a2 Improve handling of signals with threads or functions call 2020-11-21 11:06:16 +01:00
ptitSeb 2e891b807c [DYNAREC] Added 66 0F 38 08/09/0A opcodes (for #253 again) 2020-11-20 21:44:47 +01:00
ptitSeb f0b236df88 [DYNAREC] Added 66 0F 38 1C/1D/1E opcodes (still for #253) 2020-11-20 21:18:42 +01:00
ptitSeb 08904dbe0d [DYNAREC] Added 66 0F E4/E5/EA/EE opcodes (should help #253) 2020-11-20 21:04:45 +01:00
ptitSeb c9c4e226af Added 0F DA PMINUB and 0F DE PMAXUB opcodes ([DYNAREC] too) 2020-11-18 21:21:42 +01:00
ptitSeb ab3dc70145 Added 2 clipboard function to gtk2 wrapped lib 2020-11-18 20:50:06 +01:00
ptitSeb 4d8c841f3f [DYNAREC] Fix potential BUSERROR of F3 0F 2C and F3 0F 2D opcode, and fixed a typo on F3 0F E6 opcode 2020-11-18 20:44:38 +01:00
ptitSeb a8b247cde9 More improvments and fixes to signal handler 2020-11-18 19:29:52 +01:00
ptitSeb 416e161285 Added F2 0F D0 ADDSUBPS Gx, Ex opcode 2020-11-18 15:28:21 +01:00
ptitSeb cc8d1f9bf2 Better handling of signals 2020-11-18 09:58:55 +01:00
ptitSeb ae95f1b0e5 One more wrapped func tion with callback to gtk2 2020-11-17 10:35:29 +01:00
ptitSeb c10441bec4 Added g_timeout_* wrapped functions to libglib2 2020-11-17 10:27:43 +01:00
ptitSeb 6ab334fc34 Fixed a nasty typo in wrapped libgobject2 2020-11-17 10:27:20 +01:00
ptitSeb 10e849ce60 Fixed a warning in generated wrapper.c 2020-11-17 10:03:35 +01:00
ptitSeb c2206f5452 Aligned most of GValue handling in gtk libs 2020-11-17 09:41:18 +01:00
ptitSeb 3b66cd3cee Merge branch 'master' of https://github.com/ptitSeb/box86 2020-11-16 22:20:11 +01:00
ptitSeb 731a083bb7 Merge pull request #251 from daitj/makemkvtest
added few more wrapper for libcrypto (for #250)
2020-11-16 22:18:25 +01:00
Binay Devkota d35c6ab864 added more wrapper function for #250 2020-11-16 22:51:28 +02:00
Binay Devkota e9cade872c fixed previous commit as i am blind 2020-11-16 20:42:46 +02:00
Binay Devkota b2a8146851 added missing wrapped function for libcrypto #250 2020-11-16 20:15:53 +02:00
ptitSeb 6fd3d6c452 Improved handling of 'marshal' function in gobject2 2020-11-16 19:06:25 +01:00
ptitSeb bc3e72a87d Added a few more wrapped function to libcrypto (for #250) 2020-11-16 17:28:18 +01:00
ptitSeb e50e050aa9 Added some AES_* wrapped funciton to libcrypto (for #250) 2020-11-16 16:45:36 +01:00
ptitSeb c1a75607fa Fixed 'Alternate' autobridge on Interpretor 2020-11-16 14:57:37 +01:00
ptitSeb b203cd2af3 Added system 242 and 241 (for #250) 2020-11-16 14:39:39 +01:00
ptitSeb 84063f026f Added gtk_recent_filter_* wrapped function to gtk2 2020-11-16 14:39:12 +01:00
ptitSeb 3ec1ce25d7 [DYNAREC] Remove a leftover of debug trace 2020-11-16 14:35:54 +01:00
ptitSeb 0e70c543ee Added 'Aternate' solution for Gtk Classes functions beeing called in x86 code 2020-11-16 14:19:16 +01:00
ptitSeb e4d522a8d2 Refactored Gtk Class wrapping code 2020-11-16 10:25:32 +01:00
ptitSeb 272ecbd8ff More gtk class wrapping 2020-11-16 09:44:01 +01:00
ptitSeb 369fa03f9b Better handling of gtk signals 2020-11-15 18:28:25 +01:00
ptitSeb 1675ea3ba2 Added 2 functions wrapped libX11 2020-11-15 17:12:43 +01:00
ptitSeb 5b7a1bb9e6 Added phtread_spin handling 2020-11-15 17:07:07 +01:00
ptitSeb ace3effa2d Improved GCallback handling and fixed g_action_group_add_actions 2020-11-15 17:04:07 +01:00
ptitSeb bd0a14b3ce Added g_list_find_custom wrapped function to libglib2 2020-11-15 16:21:55 +01:00
ptitSeb 29a82f83c5 Added g_queue_find_custom to wrapped libglib2 2020-11-15 16:13:17 +01:00
ptitSeb f7232f09de Fixed a warning 2020-11-15 16:12:47 +01:00
ptitSeb f3eeae9edd Implemented gtk_builder_connect_signals to wrapped gtk2 2020-11-15 15:29:44 +01:00
ptitSeb 874468ca07 Added gtk_cell_layout_set_cell_data_func to gtk2 wrapped lib 2020-11-15 13:49:59 +01:00
ptitSeb 7a972af610 Fixed potential issue with gobject2 signal handler 2020-11-15 12:57:37 +01:00
ptitSeb 4ed42c38c9 Added wrapping of GtkLabel class to gtk2/3 libs 2020-11-15 12:55:31 +01:00
ptitSeb 6a73719a6b One more wrapped function to gtk2 2020-11-15 12:29:58 +01:00
ptitSeb 6efcfc6b93 Added 2 more g_list_ function to wrapped libglib2 2020-11-15 12:28:38 +01:00
ptitSeb 25f30c220e Added gtk_viewport_* wrapped function to gtk2 2020-11-15 12:24:42 +01:00
ptitSeb 2e9665f10e One more glib2 wrapped function 2020-11-15 12:22:23 +01:00
ptitSeb 197881b430 Fixed g_build_path wrapped function 2020-11-15 12:20:37 +01:00
ptitSeb 96fe98d71f Added gtk_cell_renderer_* wrapped function to gtk2 2020-11-15 11:54:35 +01:00
ptitSeb d1ecd4c933 Added g_build_path wrapped function to libglib2 2020-11-15 11:44:15 +01:00
ptitSeb fad25caa08 Added g_content_type_* function to wrapped libgio2 2020-11-15 11:34:25 +01:00
ptitSeb 98c481e045 Added gtk_tree_store wrapped functions to gtk2 lib 2020-11-15 11:29:48 +01:00
ptitSeb 6082e655e6 Added g_slist_sort and g_slist_sort_with_data to wrapped libglib2 2020-11-15 11:11:44 +01:00
ptitSeb 6a97367242 Made GetNativeFnc smarter, and should find more native funcs now 2020-11-15 11:05:07 +01:00
ptitSeb bbcfffdab9 Added gtk_container_foreach and fixed gtk_binding_entry_add_signal when n is 0 in wrapped gtk2 2020-11-15 10:28:22 +01:00
ptitSeb 2dfb6c1012 Added g_regex function to wrapped libglib2 2020-11-15 10:11:12 +01:00
ptitSeb 82317343aa Added GtkAction wrapped functions 2020-11-15 09:58:55 +01:00
ptitSeb 0ea0d0ec98 Better handling of custom gtk class, plus a bunch of gtk wrapeed functions 2020-11-15 09:48:10 +01:00
ptitSeb 33aa27c590 Added GtkAction Class handling (gtk2 and gtk3, hopefully it's the same) 2020-11-14 16:17:04 +01:00
ptitSeb c31f990183 Added F3 0F 12 MOVSLDUP Ex, Gx opcode ([DYNAREC] too) 2020-11-14 15:11:52 +01:00
ptitSeb 791956bee0 More wrapped function to gtk2 lib 2020-11-14 15:03:57 +01:00
ptitSeb 6cebf4f6fd Added more wrapped functions to gtk2 lib 2020-11-14 14:46:02 +01:00
ptitSeb 1782136e02 Added F3 0F 16 MOVSHDUP Ex, Gx opcode ([DYNAREC] too) 2020-11-14 14:30:44 +01:00
ptitSeb 2f381192dd Added some queue wrapped function to libglib2 2020-11-14 13:30:51 +01:00
ptitSeb dac2009cab Added the random functions to wrapped libglib2 2020-11-14 12:39:17 +01:00
ptitSeb d592af694f Added some more wrapped functions to libglib2 2020-11-14 12:18:56 +01:00
ptitSeb e5ea3f9e49 Added g_set_print_handler and g_set_printerr_handler to wrapped libglib2 2020-11-14 11:55:01 +01:00
ptitSeb f0af865401 Fix potential crash on exit for app using Pulse (fixes Iconoclash crash on exit) 2020-11-14 11:37:30 +01:00
ptitSeb 1e20a9effe Improved and simplifiex SDL2_mixer wrapped library 2020-11-13 22:33:34 +01:00
ptitSeb ce968f7756 Added some precision on 32bits build over 64bits OS 2020-11-12 17:43:03 +01:00
ptitSeb 00aaf316ef Added RK3399 target and compilation guide (plus some restructuration in CMake project 2020-11-11 18:08:16 +01:00
ptitSeb 3ad9a0ca73 [DYNAREC] Added ability to track exact x86 address in dynablocks for signal handling 2020-11-11 14:08:53 +01:00
ptitSeb 14a2d24fba [DYNAREC] Better way to prevent difference in emited dynablock between pass2 and pass3 2020-11-10 19:13:07 +01:00
ptitSeb e374886fcf AddedF0 90..97 opcode, simply ignoring F0 LOCK prefix ([DYNREC] too) 2020-11-09 15:09:43 +01:00
ptitSeb e25b373f00 Fixed gtk_menu_item_set_use_underline wrapped function signature 2020-11-09 12:06:57 +01:00
ptitSeb 6fbd270d24 [DYNAREC] cosmetic change 2020-11-08 13:40:40 +01:00
ptitSeb 6adb55a9c4 [DYNAREC] Try to fix the randow issue were a block have a different emited size between pass2 and pass3 2020-11-08 13:40:14 +01:00
ptitSeb 16aa5cac04 Fixed a warning with wrapped posix_spawnp 2020-11-08 13:39:06 +01:00
ptitSeb dca0009df5 [DYNAREC] Fix 66 0F 16 MOVHPD opcode and improved 66 0F C6 SHUFPD 2020-11-08 13:32:28 +01:00
ptitSeb 1cae441cbc More glib2 wrapped functions 2020-11-07 11:27:28 +01:00
ptitSeb 8b21d8f74a [DYNAREC] Added some dump of block when incosistancy between pass2 and pass3 is detected 2020-11-07 11:26:40 +01:00
ptitSeb ff141e30ee Added handling of environ instead of envv for box86 called with spawnp 2020-11-07 11:25:54 +01:00
ptitSeb 2c970a1b8d Added wrapped posix_spawnp function 2020-11-07 11:25:12 +01:00
ptitSeb b433f8194e Improved a bit the fork wrapped function 2020-11-06 17:47:53 +01:00
ptitSeb 7b2f5e5de0 Improved some BOX86_LOG=2 traces 2020-11-06 17:47:26 +01:00
ptitSeb 3d1400e347 Added preliminary gtk3/gdk3 wrapped lib (based on gtk2/gdk2 wrapping) 2020-11-06 14:08:10 +01:00
ptitSeb 8b5d68f79b Use std=gnu11 to avoid some warning when using clang 2020-11-05 14:01:32 +01:00
ptitSeb ded4b461b4 Some more check to help build on some Linux on Android env. 2020-11-05 12:48:44 +01:00
ptitSeb 13a7be57f2 Check some define to help build on some Linux on Android env. 2020-11-05 12:21:55 +01:00
ptitSeb e8fdcd5c06 Added a bunch of gtk wrapped functions 2020-11-05 11:34:11 +01:00
ptitSeb b8e263d7e6 Removed a warning in wrapped SDL_mixer 2020-11-05 11:33:50 +01:00
ptitSeb b76d17e7b9 Update ChangeLog 2020-11-04 13:15:57 +01:00
ptitSeb ce3151b256 Fixed some (XX)printf alignement issue when formating have %+ or %- command 2020-11-02 16:19:39 +01:00
ptitSeb dd0c3ac51e [VULKAN] More work on vulkan wrapper 2020-11-02 13:32:38 +01:00
ptitSeb f06c5897db Merge pull request #245 from linkmauve/patch-1
Fix install target after previous change
2020-11-02 12:51:14 +01:00
linkmauve 7dac72f796 Fix install target after previous change
#244 broke the install target because system/box86.conf should
now be taken from the build directory, sorry for that.
2020-11-02 12:10:29 +01:00
ptitSeb e5a55114b7 Merge pull request #239 from SpacingBat3/master
PKGBUILDs for Arch Linux.
2020-11-02 12:02:57 +01:00
ptitSeb a66d0b3d39 Merge pull request #244 from linkmauve/fix-binfmt-path
Generate binfmt so it points to the correct path
2020-11-02 12:00:29 +01:00
Emmanuel Gil Peyrot b01ad69ba1 Generate binfmt so it points to the correct path
CMake’s templating language is suitable for this kind of generation, as
it knows about all of the variables that have been set at configure-
time.
2020-11-02 10:52:25 +00:00
ptitSeb bbe183e8d4 Do not try to run winedbg 2020-11-01 23:29:20 +01:00
ptitSeb f6c9e5079a Small improvement on BOX86_LOG=2 2020-11-01 23:28:54 +01:00
ptitSeb 0b8408d50a [VULKAN] Fixed vkGetPhysicalDeviceImageFormatProperties signature 2020-11-01 22:42:20 +01:00
ptitSeb 51682eac11 [VULKAN] Fixed vkalignStruct/vkunalignStruct (and now Sascha-willems samples start working) 2020-11-01 21:34:23 +01:00
ptitSeb aea38c682c [VULKAN] More vulka wrapping work 2020-11-01 21:12:56 +01:00
ptitSeb 6edbe97290 Added the last function not wrapped in SDL1_mixer, and redid the wrapping of the callback (for #243) 2020-11-01 20:11:23 +01:00
ptitSeb 304eaab4d2 [VULKAN] Fixed a warning 2020-11-01 17:11:53 +01:00
ptitSeb f4e5839931 [VULKAN] Morework on wrapped functions 2020-11-01 15:35:53 +01:00
ptitSeb 4bac9ea9d5 [VULKAN] More work on vulkan wrapper 2020-11-01 10:04:30 +01:00
ptitSeb 64c9b21849 [VULKAN] Alignment of many structures. Now a simple TriangleDrawing windows App works 2020-10-31 22:58:58 +01:00
SpacingBat3 34828b66a2 Added a PKGBUILDs for other platforms. 2020-10-31 17:35:06 +01:00
SpacingBat3 957ba00723 Added a PKGBUILD for other raspberries.
Added a unified PKGBUILD to install box86 on all RPi-based machines (that are fully supported by box86) and did some changes to README.md.
2020-10-31 17:32:45 +01:00
SpacingBat3 d548ee48c1 Added a RPI4B PKGBUILD.
It is possible now to install the `box86` using the PKBUILD providen in the repository.
2020-10-31 16:57:09 +01:00
ptitSeb d0e93a22a2 Better vulkan log 2020-10-31 09:55:49 +01:00
ptitSeb fe6c1e260b Added one more vulkan extension 2020-10-31 09:55:33 +01:00
ptitSeb 1e5add91d3 Fixed many vulkan wrapped function (and now vulkaninfo works) 2020-10-30 22:12:55 +01:00
ptitSeb f4c7329c30 Forgotten in previous commit 2020-10-30 22:12:11 +01:00
ptitSeb b1742ccb8e Added some minimum wrapped libwayland-client 2020-10-30 22:11:37 +01:00
ptitSeb 870a0d8361 [VULKAN] Fixed library not found even if present 2020-10-30 17:52:44 +01:00
ptitSeb 1f0adf92d4 Added 64 8E MOV Seg, FS:Ed opcode (for #241) 2020-10-30 16:15:45 +01:00
ptitSeb 18ce562698 Wrapping of vulkan (untested yet) 2020-10-30 16:08:46 +01:00
ptitSeb 77af926336 Added 64 8C MOV FS:Ed, Seg opcode (for #241) 2020-10-30 10:44:32 +01:00
ptitSeb 33f2269896 [DYNAREC] removes some compile warning 2020-10-30 10:43:52 +01:00
ptitSeb c477e14a04 [DYNAREC] Minor chenges to some 67 xx opcodes 2020-10-30 10:10:36 +01:00
ptitSeb 373494094a [DYNAREC] Forgot that file on previous commit 2020-10-30 10:08:46 +01:00
ptitSeb 72ca666007 [DYNAREC] Added 65 80/82 opcodes 2020-10-30 10:07:47 +01:00
ptitSeb 5be299b897 [DYNAREC] Cosmetic change 2020-10-30 10:06:55 +01:00
ptitSeb 49afd5077b [DYNAREC] Fixed some function that needs flags before CALL (fixed some ESP not properly preserved on some Windows programs) 2020-10-30 10:05:47 +01:00
ptitSeb e7336de8a7 Change COMPILE.md for Pi4: make -j4 is enough 2020-10-30 10:03:10 +01:00
ptitSeb 5b0f4f5b94 Start a new developpement cycle 2020-10-30 10:02:17 +01:00
203 changed files with 22176 additions and 4921 deletions

No files matched your search

+29
View File
@@ -1,3 +1,32 @@
v0.1.8
======
* Fixes on some float to int x87 convertions opcodes
* Reworked all callback mecanisms
* Added libturbojpeg wrapping (and a hack for zoom to force using native one)
* Added BOX86_SAFEMMAP env. var.
* Reworked dynarec memory manager
* Added a few opcodes
* Improve elfloader to not force PltResolver all the time (fixing SuperHexagon and maybe other)
* Reworked Exet and Cancel Thread mecanism
* Added wrapped libldap_r and liblber library (used by wine)
* Reworked Dynarec block handling, and remove the "AddMark" mecanism that wasn't efficient enough
* Added TokiTori 2+ detection and runtime patch on PI
* Fixes on elfloader with TLS object
v0.1.6
======
* Changes in Dynarec to make flags optimizations before CALL and RET opcode less aggressive
* Added Vulkan wrapper
* Improved wrapping of SDL_mixer/ SDL2_mixer lib
* Improved wrapping of some gtk structures
* Added a quick and dirty wrapping of Gtk3 (based on current gtk2)
* Improved the signal handling, should be more stable now (the signal handler from syscall still need some works)
* Added RK3399 profile, and some hints to build the 32bits box86 on 64bits OS
* Fixed some wrapped printf formating not handled correctly
* Fixed some buserror with the new LOCK mecanism handling
* A few more Dynarec opcodes added
* If winedbg is tried to be launched, exit without launching it (it doesn't work anyway)
v0.1.4
======
* Change in Dynarec memory handling, to simplify it (and hopefully optimized it)
+45 -39
View File
@@ -1,25 +1,26 @@
cmake_minimum_required(VERSION 2.6)
project(box86)
enable_testing()
enable_language(C)
cmake_minimum_required(VERSION 3.0)
option(PANDORA "Set to ON if targeting an OpenPandora device" ${PANDORA})
option(PYRA "Set to ON if targeting an OpenPandora device" ${PYRA})
option(RPI2 "Set to ON if targeting an RaspberryPI2 device" ${RPI2})
option(RPI3 "Set to ON if targeting an RaspberryPI3 device" ${RPI3})
option(RPI4 "Set to ON if targeting an RaspberryPI4 device" ${RPI4})
option(RK3399 "Set to ON if targeting an Rockchip RK3399 based device" ${RK3399})
option(GAMESHELL "Set to ON if targeting a GameShell device" ${GAMESHELL})
option(ODROID "Set to ON if targeting an ODroid device" ${ODROID})
option(USE_CCACHE "Set to ON to use ccache if present in the system" ${USE_CCACHE})
option(LD80BITS "Set to ON if host device have 80bits long double (i.e. i386)" ${LD80BITS})
option(NOALIGN "Set to ON if host device doesn't need re-align (i.e. i386)" ${NOALIGN})
option(HAVE_TRACE "Set to ON to have Trace ability (needs ZydisInfo library)" ${HAVE_TRACE})
option(NOLOADADDR "Set to ON to avoid fixing the load address of Box86" ${NO_LOADAADR})
option(ARM_DYNAREC "Set to ON to use ARM Dynamic Recompilation (WIP, don't use yet)" ${ARM_DYNAREC})
option(NOGETCLOCK "Set to ON to avoid using clock_gettime with CLOCK_MONOTONIC_COARSE for RDTSC opcode (use gltimeofday instead)" ${NOGETCLOCK})
option(NOGIT "Set to ON if not building from a git clone repo (like when building from a zip download from github)" ${NOGIT})
if(PANDORA OR PYRA OR RPI2 OR RPI3 OR RPI4 OR GAMESHELL OR ODROID OR RK3399)
set(LD80BITS OFF CACHE BOOL "")
set(NOALIGN OFF CACHE BOOL "")
set(ARM_DYNAREC ON CACHE BOOL "")
endif()
option(LD80BITS "Set to ON if host device have 80bits long double (i.e. i386)" ${LD80BITS})
option(NOALIGN "Set to ON if host device doesn't need re-align (i.e. i386)" ${NOALIGN})
option(ARM_DYNAREC "Set to ON to use ARM Dynamic Recompilation (WIP, don't use yet)" ${ARM_DYNAREC})
if(${CMAKE_VERSION} VERSION_LESS "3.12.2")
find_package(PythonInterp 3)
@@ -37,6 +38,16 @@ else()
set(PYTHON_EXECUTABLE ${Python3_EXECUTABLE} CACHE INTERNAL "The Python3 executable" FORCE)
endif()
if(RK3399)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
#set(CMAKE_ASM_COMPILER arm-linux-gnueabihf-as) #will use gcc in fact
set(CMAKE_C_COMPILER_TARGET arm-linux-gnueabihf)
endif()
project(box86 C ASM)
enable_testing()
set(default_build_type "RelwithDebInfo")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
@@ -44,66 +55,47 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
# Pandora
if(PANDORA)
add_definitions(-DPANDORA)
#add_definitions(-mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -ftree-vectorize -fsingle-precision-constant -ffast-math)
set(ARM_DYNAREC ON)
set(LD80BITS OFF)
set(NOALIGN OFF)
endif()
# Gameshell
if(GAMESHELL)
add_definitions(-DGAMEHELL)
add_definitions(-marm -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard)
set(CMAKE_ASM_FLAGS "-marm -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard")
set(ARM_DYNAREC ON)
set(LD80BITS OFF)
set(NOALIGN OFF)
endif()
if(PYRA)
add_definitions(-DPYRA)
add_definitions(-mcpu=cortex-a15 -mfpu=neon -mfloat-abi=hard -marm)
set(CMAKE_ASM_FLAGS "-marm -mcpu=cortex-a15 -mfpu=neon -mfloat-abi=hard")
set(ARM_DYNAREC ON)
set(LD80BITS OFF)
set(NOALIGN OFF)
endif()
if(RPI2)
add_definitions(-DRPI)
add_definitions(-DRPI2)
add_definitions(-marm -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard)
set(CMAKE_ASM_FLAGS "-marm -mcpu=cortex-a7 -mfpu=neon-vfpv4 -mfloat-abi=hard")
set(ARM_DYNAREC ON)
set(LD80BITS OFF)
set(NOALIGN OFF)
endif()
if(RPI3)
add_definitions(-DRPI)
add_definitions(-DRPI3)
add_definitions(-marm -march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard)
set(CMAKE_ASM_FLAGS "-marm -march=armv8-a+crc -mtune=cortex-a53 -mfpu=neon-fp-armv8 -mfloat-abi=hard")
set(ARM_DYNAREC ON)
set(LD80BITS OFF)
set(NOALIGN OFF)
endif()
if(RPI4)
add_definitions(-DRPI)
add_definitions(-DRPI3)
add_definitions(-DRPI4)
add_definitions(-marm -march=armv8-a+crc -mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard)
set(CMAKE_ASM_FLAGS "-marm -march=armv8-a+crc -mtune=cortex-a72 -mfpu=neon-fp-armv8 -mfloat-abi=hard")
set(ARM_DYNAREC ON)
set(LD80BITS OFF)
set(NOALIGN OFF)
endif()
if(ODROID)
add_definitions(-DODROID)
add_definitions(-mcpu=cortex-a9 -mfpu=neon-vfpv4 -mfloat-abi=hard -marm)
set(CMAKE_ASM_FLAGS "-marm -mcpu=cortex-a9 -mfpu=neon-vfpv4 -mfloat-abi=hard")
set(ARM_DYNAREC ON)
set(LD80BITS OFF)
set(NOALIGN OFF)
endif()
if(RK3399)
add_definitions(-DRK3399)
add_definitions(-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a72+crypto)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a72+crypto")
endif()
if(NOGIT)
@@ -158,7 +150,7 @@ else()
endif()
add_definitions(-std=gnu99 -funwind-tables -fvisibility=hidden)
add_definitions(-std=gnu11 -funwind-tables -fvisibility=hidden)
if(USE_CCACHE)
find_program(CCACHE_FOUND ccache)
@@ -218,6 +210,7 @@ set(ELFLOADER_SRC
"${BOX86_ROOT}/src/libtools/sdl2rwops.c"
"${BOX86_ROOT}/src/libtools/signals.c"
"${BOX86_ROOT}/src/libtools/threads.c"
"${BOX86_ROOT}/src/libtools/vkalign.c"
"${BOX86_ROOT}/src/dynarec/dynarec.c"
"${BOX86_ROOT}/src/wrapped/generated/wrapper.c"
)
@@ -239,6 +232,7 @@ set(WRAPPEDS
"${BOX86_ROOT}/src/wrapped/wrappedsdl2.c"
"${BOX86_ROOT}/src/wrapped/wrappedsdl2mixer.c"
"${BOX86_ROOT}/src/wrapped/wrappedsdl2image.c"
"${BOX86_ROOT}/src/wrapped/wrappedsdl2ttf.c"
"${BOX86_ROOT}/src/wrapped/wrappedsmpeg.c"
"${BOX86_ROOT}/src/wrapped/wrappedsmpeg2.c"
"${BOX86_ROOT}/src/wrapped/wrappedvorbisfile.c"
@@ -280,6 +274,7 @@ set(WRAPPEDS
"${BOX86_ROOT}/src/wrapped/wrappedalut.c"
"${BOX86_ROOT}/src/wrapped/wrappedlibjpeg.c"
"${BOX86_ROOT}/src/wrapped/wrappedlibjpeg62.c"
"${BOX86_ROOT}/src/wrapped/wrappedturbojpeg.c"
"${BOX86_ROOT}/src/wrapped/wrappedcurl.c"
"${BOX86_ROOT}/src/wrapped/wrappedudev0.c"
"${BOX86_ROOT}/src/wrapped/wrappedudev1.c"
@@ -308,6 +303,8 @@ set(WRAPPEDS
"${BOX86_ROOT}/src/wrapped/wrappedlibtinfo6.c"
"${BOX86_ROOT}/src/wrapped/wrappedgtkx112.c"
"${BOX86_ROOT}/src/wrapped/wrappedgdkx112.c"
"${BOX86_ROOT}/src/wrapped/wrappedgtk3.c"
"${BOX86_ROOT}/src/wrapped/wrappedgdk3.c"
"${BOX86_ROOT}/src/wrapped/wrappedgdkpixbuf2.c"
"${BOX86_ROOT}/src/wrapped/wrappedgio2.c"
"${BOX86_ROOT}/src/wrapped/wrappedgmodule2.c"
@@ -332,6 +329,14 @@ set(WRAPPEDS
"${BOX86_ROOT}/src/wrapped/wrappedgnutls.c"
"${BOX86_ROOT}/src/wrapped/wrappedlibcups.c"
"${BOX86_ROOT}/src/wrapped/wrappedd3dadapter9.c"
"${BOX86_ROOT}/src/wrapped/wrappedvulkan.c"
"${BOX86_ROOT}/src/wrapped/wrappedwaylandclient.c"
"${BOX86_ROOT}/src/wrapped/wrappedxml2.c"
"${BOX86_ROOT}/src/wrapped/wrappedxslt.c"
"${BOX86_ROOT}/src/wrapped/wrappedldapr.c"
"${BOX86_ROOT}/src/wrapped/wrappedlber.c"
"${BOX86_ROOT}/src/wrapped/wrappedlcms2.c"
"${BOX86_ROOT}/src/wrapped/wrappednsl.c"
"${BOX86_ROOT}/src/wrapped/wrappedldlinux.c"
)
@@ -497,7 +502,8 @@ string(COMPARE EQUAL "${CMAKE_HOST_SYSTEM_PROCESSOR}" "x86_64" _x86_64)
if(NOT _x86 AND NOT _x86_64)
install(TARGETS ${BOX86}
RUNTIME DESTINATION bin)
install(FILES ${CMAKE_SOURCE_DIR}/system/box86.conf DESTINATION /etc/binfmt.d/)
configure_file(system/box86.conf.cmake system/box86.conf)
install(FILES ${CMAKE_BINARY_DIR}/system/box86.conf DESTINATION /etc/binfmt.d/)
install(FILES ${CMAKE_SOURCE_DIR}/x86lib/libstdc++.so.6 DESTINATION /usr/lib/i386-linux-gnu/)
install(FILES ${CMAKE_SOURCE_DIR}/x86lib/libstdc++.so.5 DESTINATION /usr/lib/i386-linux-gnu/)
install(FILES ${CMAKE_SOURCE_DIR}/x86lib/libgcc_s.so.1 DESTINATION /usr/lib/i386-linux-gnu/)
+7 -1
View File
@@ -20,7 +20,7 @@ Compiling
git clone https://github.com/ptitSeb/box86
cd box86
mkdir build; cd build; cmake .. -DRPI4=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
make -j24
make -j4
sudo make install
sudo systemctl restart systemd-binfmt
```
@@ -31,6 +31,12 @@ sudo systemctl restart systemd-binfmt
`mkdir build; cd build; cmake .. -DODROID=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make`
#### for RK3399
`mkdir build; cd build; cmake .. -DRK3399=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j4`
As most RK3399 device run AARCH64 OS, you'll need an `armhf` multiarch env, and an armhf gcc: use `sudo apt install gcc-arm-linux-gnueabihf` to install it.
#### for Other ARM Linux
`mkdir build; cd build; cmake .. -DARM_DYNAREC=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo; make`
+4 -2
View File
@@ -5,7 +5,7 @@ Linux Userspace x86 Emulator with a twist
Box86 lets you run x86 Linux programs (such as games) on non-x86 Linux, like ARM (host system needs to be 32bit little-endian).
You *NEED* a 32-bit subsystem to run and build Box86. Box86 is useless on 64-bit only systems. Also, you *NEED* a 32-bit toolchain to build Box86. A toolchain that only support 64-bit will not compile Box86, and you'll get errors (typically on aarch64, you get "-marm" not recognized).
You *NEED* a 32-bit subsystem to run and build Box86. Box86 is useless on 64-bit only systems. Also, you *NEED* a 32-bit toolchain to build Box86. A toolchain that only support 64-bit will not compile Box86, and you'll get errors (typically on aarch64, you get "-marm" not recognized, and you'll need a multiarch or chroot environnement).
Because Box86 uses the native versions of some "system" libraries, like libc, libm, SDL, and OpenGL, it's easy to integrate and use, and performance can be surprisingly high in some cases.
@@ -91,9 +91,10 @@ A note about Steam
----
Linux Steam can run now with box86. But it's still a bit unstable., and not everything works. First is steam crashes after the Sign in, you may need to add libappindicator. On debian it's `sudo apt install libappindicator1`.
Once open, Steam will only work on "Small mode". So go in the "View" menu and witch to Small view (or Compact view?), else the list will stay empty (this is because some steam component used in the browser view are only 64bits now).
Once open, Steam will only work on "Small mode" and in "Big Picture", not in the regular "Browser mode". So go in the "View" menu and witch to Small view (or Compact view?), else the list will stay empty (this is because some steam component used in the browser view are only 64bits now).
Final word, to avoid the "libc.so.6 is absent" message, you can use `STEAMOS=1` and `STEAM_RUNTIME=1` export.
(Steam for Windows install fine but doesn't work yet)
Some steam games (most of Source engine one, like "Portal" or "Half-Life 2") use libtcmalloc. Box86 will detect it's use and will try to LD_PRELOAD it, for better compatibility. While it should work without, it is better to add it to your system if you intend to play those game (something like `sudo apt install libtcmalloc-minimal4` on debian familly)
----
@@ -101,6 +102,7 @@ A note about Wine
----
Wine is now partly supported. Wine integreted program all runs, annd some windows program and games now run fine. Don't forget most Windows games use Direct3D, that may require a complete OpenGL driver and as high profile as possible (and gl4es with ES2 backend have issue with Wine for now). Also, vulkan is not wrapped on box86, so vk3d is not usable yet, even if supported by the hardware.
A not if you plan to use box86 with wine on Raspberry PI 3 or earlier: those model use a default OS that have a kernle with a 2/2 Split (meaning 2G of space for user program, and 2G of space for Kernel). This is not compatible with wine, that need to access memory > 2Gb address. So you'll need to reconfigure your kernel for a 3G/1G split. Use your favorite search engine to find tutos on how to do that.
----
+9
View File
@@ -108,6 +108,10 @@ Set level of DynaRec log
* 0 : Disable Dynarec Linker (use that on debug, with dynarec log >= 2, to have detail on wich block get executed)
* 1 : Enable Dynarec Linker (default)
#### BOX86_DYNAREC_SAFEMMAP
* 0 : Default. Some mmp/mmap64 are consider unsafe (depending of flags mainly)
* 1 : Consider all mmap/mmap64 safe to use linker (potential speedup, but potential crash for apps using JIT/Dynarec)
#### BOX86_DYNAREC_TRACE
* 0 : Disable trace for generated code (default)
* 1 : Enable trace for generated code (like regular Trace, this will slow down a lot and generate huge logs)
@@ -136,6 +140,11 @@ Disable the load of pulseaudio libs
* 0 : default, load pulseaudio libs if present
* 1 : disable the load of pulse audio libs (libpulse and libpulse-simple), both native and x86 version
#### BOX86_NOGTK
Disable the load of wrapped gtk libs
* 0 : default, load wrapped gtk libs if present
* 1 : disable the load of wrapped gtk libs (can be used with Steam, along with STEAM_RUNTIME=1 to use i386 versio of gtk)
#### BOX86_FIX_64BIT_INODES
* 0 : Don't fix 64bit inodes (default)
* 1 : Fix 64bit inodes. Helps when running on filesystems with 64bit inodes, the program uses API functions which don't support it and the program doesn't use inodes information.
+38
View File
@@ -0,0 +1,38 @@
# Maintainer: SpacingBat3 <[email protected]>
# Contributor: Sebastien Chevalier
pkgname=box86-arm-git
pkgver=r2798.0edc0374
pkgrel=1
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
arch=('armv7h')
url="https://github.com/ptitSeb/box86"
license=('MIT')
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
makedepends=('git' 'cmake' 'make')
provides=("${pkgname%-git}")
conflicts=("${pkgname%-git}")
source=('git+https://github.com/ptitSeb/box86')
md5sums=('SKIP')
pkgver() {
cd "$srcdir/${pkgname%-git}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd "${srcdir}/${pkgname%-git}"
if [[ ! -d ./build ]]; then
mkdir build && cd build
cmake .. -DARM_DYNAREC=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo
fi
}
build() {
cd "$srcdir/${pkgname%-git}/build"
make -j$(nproc)
}
package() {
cd "$srcdir/${pkgname%-git}/build"
make DESTDIR="${pkgdir}/" install
}
+38
View File
@@ -0,0 +1,38 @@
# Maintainer: SpacingBat3 <[email protected]>
# Contributor: Sebastien Chevalier
pkgname=box86-gameshell-git
pkgver=r2798.0edc0374
pkgrel=1
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
arch=('armv7h')
url="https://github.com/ptitSeb/box86"
license=('MIT')
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
makedepends=('git' 'cmake' 'make')
provides=("${pkgname%-git}")
conflicts=("${pkgname%-git}")
source=('git+https://github.com/ptitSeb/box86')
md5sums=('SKIP')
pkgver() {
cd "$srcdir/${pkgname%-git}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd "${srcdir}/${pkgname%-git}"
if [[ ! -d ./build ]]; then
mkdir build && cd build
cmake .. -DGAMESHELL=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
fi
}
build() {
cd "$srcdir/${pkgname%-git}/build"
make -j$(nproc)
}
package() {
cd "$srcdir/${pkgname%-git}/build"
make DESTDIR="${pkgdir}/" install
}
+38
View File
@@ -0,0 +1,38 @@
# Maintainer: SpacingBat3 <[email protected]>
# Contributor: Sebastien Chevalier
pkgname=box86-odroid-git
pkgver=r2798.0edc0374
pkgrel=1
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
arch=('armv7h')
url="https://github.com/ptitSeb/box86"
license=('MIT')
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
makedepends=('git' 'cmake' 'make')
provides=("${pkgname%-git}")
conflicts=("${pkgname%-git}")
source=('git+https://github.com/ptitSeb/box86')
md5sums=('SKIP')
pkgver() {
cd "$srcdir/${pkgname%-git}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd "${srcdir}/${pkgname%-git}"
if [[ ! -d ./build ]]; then
mkdir build && cd build
cmake .. -DODROID=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
fi
}
build() {
cd "$srcdir/${pkgname%-git}/build"
make -j$(nproc)
}
package() {
cd "$srcdir/${pkgname%-git}/build"
make DESTDIR="${pkgdir}/" install
}
+38
View File
@@ -0,0 +1,38 @@
# Maintainer: SpacingBat3 <[email protected]>
# Contributor: Sebastien Chevalier
pkgname=box86-pandora-git
pkgver=r2798.0edc0374
pkgrel=1
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
arch=('armv7h')
url="https://github.com/ptitSeb/box86"
license=('MIT')
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
makedepends=('git' 'cmake' 'make')
provides=("${pkgname%-git}")
conflicts=("${pkgname%-git}")
source=('git+https://github.com/ptitSeb/box86')
md5sums=('SKIP')
pkgver() {
cd "$srcdir/${pkgname%-git}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd "${srcdir}/${pkgname%-git}"
if [[ ! -d ./build ]]; then
mkdir build && cd build
cmake .. -DPANDORA=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
fi
}
build() {
cd "$srcdir/${pkgname%-git}/build"
make -j$(nproc)
}
package() {
cd "$srcdir/${pkgname%-git}/build"
make DESTDIR="${pkgdir}/" install
}
+38
View File
@@ -0,0 +1,38 @@
# Maintainer: SpacingBat3 <[email protected]>
# Contributor: Sebastien Chevalier
pkgname=box86-pyra-git
pkgver=r2798.0edc0374
pkgrel=1
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
arch=('armv7h')
url="https://github.com/ptitSeb/box86"
license=('MIT')
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
makedepends=('git' 'cmake' 'make')
provides=("${pkgname%-git}")
conflicts=("${pkgname%-git}")
source=('git+https://github.com/ptitSeb/box86')
md5sums=('SKIP')
pkgver() {
cd "$srcdir/${pkgname%-git}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd "${srcdir}/${pkgname%-git}"
if [[ ! -d ./build ]]; then
mkdir build && cd build
cmake .. -DPYRA=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
fi
}
build() {
cd "$srcdir/${pkgname%-git}/build"
make -j$(nproc)
}
package() {
cd "$srcdir/${pkgname%-git}/build"
make DESTDIR="${pkgdir}/" install
}
+52
View File
@@ -0,0 +1,52 @@
# Maintainer: SpacingBat3 <[email protected]>
# Contributor: Sebastien Chevalier
pkgname=box86-rpi-git
pkgver=r2798.0edc0374
pkgrel=1
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
arch=('armv7h')
url="https://github.com/ptitSeb/box86"
license=('MIT')
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
makedepends=('git' 'cmake' 'make')
provides=("${pkgname%-git}")
conflicts=("${pkgname%-git}")
source=('git+https://github.com/ptitSeb/box86')
md5sums=('SKIP')
_pimodel=`tr -d '\0' < /sys/firmware/devicetree/base/model`
pkgver() {
cd "$srcdir/${pkgname%-git}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd "${srcdir}/${pkgname%-git}"
# Check for Pi version number
if [[ ${_pimodel} ~= "Raspberry Pi 4" ]]; then
_piversion=4
elif [[ ${_pimodel} ~= "Raspberry Pi 3" ]]; then
_piversion=3
elif [[ ${_pimodel} ~= "Raspberry Pi 2" ]]; then
_piversion=2
else
# Your RPI is not supported or this device is not a pi, cancel build then
echo -e "\033[01m\033[01;31m==> ERROR:\033[00;01m Your device is not supported! This script is for RPi model 4/3/2 (1/0 not supported).\033[00m"
exit 1
fi
echo -e "\033[01m\033[01;34m==> INFO:\033[00;01m Your detected Pi verion number is: \033[01;31m${_piversion}\033[01m.\033[00m"
if [[ ! -d ./build ]]; then
mkdir build && cd build
cmake .. -DRPI${_piversion}=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
fi
}
build() {
cd "$srcdir/${pkgname%-git}/build"
make -j$(nproc)
}
package() {
cd "$srcdir/${pkgname%-git}/build"
make DESTDIR="${pkgdir}/" install
}
+37
View File
@@ -0,0 +1,37 @@
# Maintainer: SpacingBat3 <[email protected]>
# Contributor: Sebastien Chevalier
pkgname=box86-x86-git
pkgver=r2798.0edc0374
pkgrel=1
pkgdesc="Linux Userspace x86 Emulator with a twist, targeted at ARM Linux devices."
arch=('i386')
url="https://github.com/ptitSeb/box86"
license=('MIT')
makedepends=('git' 'cmake' 'make')
provides=("${pkgname%-git}")
conflicts=("${pkgname%-git}")
source=('git+https://github.com/ptitSeb/box86')
md5sums=('SKIP')
pkgver() {
cd "$srcdir/${pkgname%-git}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd "${srcdir}/${pkgname%-git}"
if [[ ! -d ./build ]]; then
mkdir build && cd build
cmake .. -DLD80BITS=1 -DNOALIGN=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
fi
}
build() {
cd "$srcdir/${pkgname%-git}/build"
make -j$(nproc)
}
package() {
cd "$srcdir/${pkgname%-git}/build"
make DESTDIR="${pkgdir}/" install
}
+21
View File
@@ -0,0 +1,21 @@
# The directory containing all PKGBUILDs for BOX86
## FAQ
### 1. How to use it?
Just download the `PKGBUILD-<your-platform>` (no need to download the whole repository), go to directory where you downloaded and type:
```sh
mv ./PKGBUILD-<your-platform> ./PKGBUILD
cd ..
makepkg -si
```
This will copy the PKGBUILD for your platform (where you type your platform name instead of `<your-platform>`), build it and install the PKGBUILD on 32-bit Archlinux ARM.
In the future, I might try to do an unified PKGBUILD for all platforms that will recognize your platform automatically.
### 2. What platforms are currently supported.
All specified in [COMPILE.md](../COMPILE.md).
### 3. Any advantages with that sollution?
This might give you some advantages like those:
- automatic updates (with some AUR frontends like [`pamac-aur`](https://aur.archlinux.org/packages/pamac-aur/) or [`yay`](https://aur.archlinux.org/packages/yay));
- easily uninstall with `pacman -R` when no needed (no need other scripts nor Makefile to do this);
- your `box86` installation is recognized as a package (where it wasn't when installing with `make install`).
+120 -62
View File
@@ -3,7 +3,7 @@
import os
import sys
values = ['E', 'e', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'V', 'O', 'S', '2']
values = ['E', 'e', 'v', 'c', 'w', 'i', 'I', 'C', 'W', 'u', 'U', 'f', 'd', 'D', 'K', 'l', 'L', 'p', 'V', 'O', 'S', '2', 'P', 'G']
def splitchar(s):
try:
ret = [len(s), values.index(s[0])]
@@ -252,6 +252,33 @@ static void* io_convert(void* v)
return v;
}
typedef struct my_GValue_s
{
int g_type;
union {
int v_int;
int64_t v_int64;
uint64_t v_uint64;
float v_float;
double v_double;
void* v_pointer;
} data[2];
} my_GValue_t;
static void alignGValue(my_GValue_t* v, void* value)
{
v->g_type = *(int*)value;
memcpy(v->data, value+4, 2*sizeof(double));
}
static void unalignGValue(void* value, my_GValue_t* v)
{
*(int*)value = v->g_type;
memcpy(value+4, v->data, 2*sizeof(double));
}
void* VulkanFromx86(void* src, void** save);
void VulkanTox86(void* src, void* save);
#define ST0val ST0.d
int of_convert(int);
@@ -262,6 +289,7 @@ int of_convert(int);
#ifndef __WRAPPER_H_
#define __WRAPPER_H_
#include <stdint.h>
#include <string.h>
typedef struct x86emu_s x86emu_t;
@@ -282,6 +310,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
// S = _IO_2_1_stdXXX_ pointer (or FILE*)
// Q = ...
// 2 = struct of 2 uint
// P = Vulkan struture pointer
// G = a single GValue pointer
"""
}
@@ -317,8 +347,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
# First part: typedefs
for v in gbl["()"]:
# E e v c w i I C W u U f d D K l L p V O S 2
types = ["x86emu_t*", "x86emu_t**", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "_2uint_struct_t"]
# E e v c w i I C W u U f d D K l L p V O S 2 P G
types = ["x86emu_t*", "x86emu_t**", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "_2uint_struct_t", "void*", "void*"]
if len(values) != len(types):
raise NotImplementedError("len(values) = {lenval} != len(types) = {lentypes}".format(lenval=len(values), lentypes=len(types)))
@@ -327,8 +357,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
for k in gbl_idxs:
file.write("\n#if " + k + "\n")
for v in gbl[k]:
# E e v c w i I C W u U f d D K l L p V O S 2
types = ["x86emu_t*", "x86emu_t**", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "_2uint_struct_t"]
# E e v c w i I C W u U f d D K l L p V O S 2 P G
types = ["x86emu_t*", "x86emu_t**", "void", "int8_t", "int16_t", "int32_t", "int64_t", "uint8_t", "uint16_t", "uint32_t", "uint64_t", "float", "double", "long double", "double", "intptr_t", "uintptr_t", "void*", "void*", "int32_t", "void*", "_2uint_struct_t", "void*", "void*"]
if len(values) != len(types):
raise NotImplementedError("len(values) = {lenval} != len(types) = {lentypes}".format(lenval=len(values), lentypes=len(types)))
@@ -337,8 +367,72 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
file.write("#endif\n")
file.write("\n")
# Next part: function definitions
# Helper variables
arg = [
"emu, ", # E
"&emu, ", # e
"", # v
"*(int8_t*)(R_ESP + {p}), ", # c
"*(int16_t*)(R_ESP + {p}), ", # w
"*(int32_t*)(R_ESP + {p}), ", # i
"*(int64_t*)(R_ESP + {p}), ", # I
"*(uint8_t*)(R_ESP + {p}), ", # C
"*(uint16_t*)(R_ESP + {p}), ", # W
"*(uint32_t*)(R_ESP + {p}), ", # u
"*(uint64_t*)(R_ESP + {p}), ", # U
"*(float*)(R_ESP + {p}), ", # f
"*(double*)(R_ESP + {p}), ", # d
"*(long double*)(R_ESP + {p}), ", # D
"FromLD((void*)(R_ESP + {p})), ", # K
"*(intptr_t*)(R_ESP + {p}), ", # l
"*(uintptr_t*)(R_ESP + {p}), ", # L
"*(void**)(R_ESP + {p}), ", # p
"(void*)(R_ESP + {p}), ", # V
"of_convert(*(int32_t*)(R_ESP + {p})), ", # O
"io_convert(*(void**)(R_ESP + {p})), ", # S
"(_2uint_struct_t){{*(uintptr_t*)(R_ESP + {p}),*(uintptr_t*)(R_ESP + {p} + 4)}}, ", #2
"arg{p}, ", # P
"&arg{p}, ", # G
]
# E e v c w i I C W u U f d D K l L p V O S 2 P G
deltas = [0, 0, 4, 4, 4, 4, 8, 4, 4, 4, 8, 4, 8, 12, 12, 4, 4, 4, 0, 4, 4, 8, 4, 4]
vals = [
"\n#error Invalid return type: emulator\n", # E
"\n#error Invalid return type: &emulator\n", # e
"fn({0});", # v
"R_EAX=fn({0});", # c
"R_EAX=fn({0});", # w
"R_EAX=fn({0});", # i
"ui64_t r; r.i=fn({0}); R_EAX=r.d[0]; R_EDX=r.d[1];", # I
"R_EAX=(unsigned char)fn({0});", # C
"R_EAX=(unsigned short)fn({0});", # W
"R_EAX=(uint32_t)fn({0});", # u
"ui64_t r; r.u=(uint64_t)fn({0}); R_EAX=r.d[0]; R_EDX=r.d[1];", # U
"float fl=fn({0}); fpu_do_push(emu); ST0val = fl;", # f
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # d
"long double ld=fn({0}); fpu_do_push(emu); ST0val = ld;", # D
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # K
"R_EAX=(intptr_t)fn({0});", # l
"R_EAX=(uintptr_t)fn({0});", # L
"R_EAX=(uintptr_t)fn({0});", # p
"\n#error Invalid return type: va_list\n", # V
"\n#error Invalid return type: at_flags\n", # O
"\n#error Invalid return type: _io_file*\n", # S
"\n#error Invalid return type: _2uint_struct\n", # 2
"\n#error Invalid return type: Vulkan Struct\n", # P
"\n#error Invalid return type: GValue Pointer\n", # G
]
# Asserts
if len(values) != len(arg):
raise NotImplementedError("len(values) = {lenval} != len(arg) = {lenarg}".format(lenval=len(values), lenarg=len(arg)))
if len(values) != len(deltas):
raise NotImplementedError("len(values) = {lenval} != len(deltas) = {lendeltas}".format(lenval=len(values), lendeltas=len(deltas)))
if len(values) != len(vals):
raise NotImplementedError("len(values) = {lenval} != len(vals) = {lenvals}".format(lenval=len(values), lenvals=len(vals)))
# Helper functions to write the function definitions
def function_args(args, d=4):
if len(args) == 0:
@@ -351,67 +445,31 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
elif args[0] == "1":
return "1, " + function_args(args[1:], d)
arg = [
"emu, ", # E
"&emu, ", # e
"", # v
"*(int8_t*)(R_ESP + {p}), ", # c
"*(int16_t*)(R_ESP + {p}), ", # w
"*(int32_t*)(R_ESP + {p}), ", # i
"*(int64_t*)(R_ESP + {p}), ", # I
"*(uint8_t*)(R_ESP + {p}), ", # C
"*(uint16_t*)(R_ESP + {p}), ", # W
"*(uint32_t*)(R_ESP + {p}), ", # u
"*(uint64_t*)(R_ESP + {p}), ", # U
"*(float*)(R_ESP + {p}), ", # f
"*(double*)(R_ESP + {p}), ", # d
"*(long double*)(R_ESP + {p}), ", # D
"FromLD((void*)(R_ESP + {p})), ", # K
"*(intptr_t*)(R_ESP + {p}), ", # l
"*(uintptr_t*)(R_ESP + {p}), ", # L
"*(void**)(R_ESP + {p}), ", # p
"(void*)(R_ESP + {p}), ", # V
"of_convert(*(int32_t*)(R_ESP + {p})), ", # O
"io_convert(*(void**)(R_ESP + {p})), ", # S
"(_2uint_struct_t){{*(uintptr_t*)(R_ESP + {p}),*(uintptr_t*)(R_ESP + {p} + 4)}}, ", #2
]
# E e v c w i I C W u U f d D K l L p V O S 2
deltas = [0, 0, 4, 4, 4, 4, 8, 4, 4, 4, 8, 4, 8, 12, 12, 4, 4, 4, 0, 4, 4, 8]
if len(values) != len(arg):
raise NotImplementedError("len(values) = {lenval} != len(arg) = {lenarg}".format(lenval=len(values), lenarg=len(arg)))
if len(values) != len(deltas):
raise NotImplementedError("len(values) = {lenval} != len(deltas) = {lendeltas}".format(lenval=len(values), lendeltas=len(deltas)))
return arg[values.index(args[0])].format(p=d) + function_args(args[1:], d + deltas[values.index(args[0])])
def function_writer(f, N, W, rettype, args):
f.write("void {0}(x86emu_t *emu, uintptr_t fcn) {2} {1} fn = ({1})fcn; ".format(N, W, "{"))
vals = [
"\n#error Invalid return type: emulator\n", # E
"\n#error Invalid return type: &emulator\n", # e
"fn({0});", # v
"R_EAX=fn({0});", # c
"R_EAX=fn({0});", # w
"R_EAX=fn({0});", # i
"ui64_t r; r.i=fn({0}); R_EAX=r.d[0]; R_EDX=r.d[1];", # I
"R_EAX=(unsigned char)fn({0});", # C
"R_EAX=(unsigned short)fn({0});", # W
"R_EAX=(uint32_t)fn({0});", # u
"ui64_t r; r.u=(uint64_t)fn({0}); R_EAX=r.d[0]; R_EDX=r.d[1];", # U
"float fl=fn({0}); fpu_do_push(emu); ST0val = fl;", # f
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # d
"long double ld=fn({0}); fpu_do_push(emu); ST0val = ld;", # D
"double db=fn({0}); fpu_do_push(emu); ST0val = db;", # K
"R_EAX=(intptr_t)fn({0});", # l
"R_EAX=(uintptr_t)fn({0});", # L
"R_EAX=(uintptr_t)fn({0});", # p
"\n#error Invalid return type: va_list\n", # V
"\n#error Invalid return type: at_flags\n", # O
"\n#error Invalid return type: _io_file*\n", # S
"\n#error Invalid return type: _2uint_srtuct\n", # 2
]
if len(values) != len(vals):
raise NotImplementedError("len(values) = {lenval} != len(vals) = {lenvals}".format(lenval=len(values), lenvals=len(vals)))
f.write(vals[values.index(rettype)].format(function_args(args)[:-2]) + " }\n")
if any(cc in 'PG' for cc in args):
# Vulkan struct or GValue pointer, need to unwrap functions at the end
delta = 4
for c in args:
if c == 'P':
f.write("void* save{d}=NULL; void *arg{d} = VulkanFromx86(*(void**)(R_ESP + {d}), &save{d}); ".format(d=delta))
if c == 'G':
f.write("my_GValue_t arg{d}; alignGValue(&arg{d}, *(void**)(R_ESP + {d})); ".format(d=delta))
delta = delta + deltas[values.index(c)]
f.write(vals[values.index(rettype)].format(function_args(args)[:-2]) + " ")
delta = 4
for c in args:
if c == 'P':
f.write("VulkanTox86(arg{d}, save{d}); ".format(d=delta))
if c == 'G':
f.write("unalignGValue(*(void**)(R_ESP + {d}), &arg{d}); ".format(d=delta))
delta = delta + deltas[values.index(c)]
f.write("}\n")
else:
# Generic function
f.write(vals[values.index(rettype)].format(function_args(args)[:-2]) + " }\n")
for v in gbl["()"]:
function_writer(file, v, v + "_t", v[0], v[2:])
+282 -154
View File
@@ -22,192 +22,303 @@
#ifdef DYNAREC
#include <sys/mman.h>
#include "dynablock.h"
#include "khash.h"
#define MMAPSIZE (4*1024*1024) // allocate 4Mo sized blocks
#define MMAPBLOCK 256 // minimum size of a block
//#define USE_MMAP
#define MMAPSIZE (256*1024) // allocate 256kb sized blocks
// init inside dynablocks.c
KHASH_MAP_INIT_INT(dynablocks, dynablock_t*)
typedef union mark_s {
struct {
unsigned int fill:1;
unsigned int size:31;
};
uint32_t x32;
} mark_t;
typedef struct blockmark_s {
mark_t prev;
mark_t next;
} blockmark_t;
typedef struct mmaplist_s {
void* block;
uint8_t map[MMAPSIZE/(8*MMAPBLOCK)]; // map of allocated sub-block
void* block;
int maxfree;
kh_dynablocks_t* dblist;
} mmaplist_t;
// get first subblock free in map, stating at start. return -1 if no block, else first subblock free, filling size (in subblock unit)
static int getFirstBlock(mmaplist_t *map, int start, int maxsize, int* size)
// get first subblock free in block, stating at start (from block). return NULL if no block, else first subblock free (mark included), filling size
static void* getFirstBlock(void* block, int maxsize, int* size)
{
#define ISFREE(A) (((map->map[(A)>>3]>>((A)&7))&1)?0:1)
if(start<0) start = 0;
while(start<MMAPSIZE/(8*MMAPBLOCK)) { // still a chance...
if(ISFREE(start)) {
// free, now get size...
int end = start+1;
while(end<MMAPSIZE/(8*MMAPBLOCK)) {
if(!ISFREE(end) || (end-start==maxsize)) {
if(size) *size = end-start;
return start;
// get start of block
blockmark_t *m = (blockmark_t*)block;
while(m->next.x32) { // while there is a subblock
if(!m->next.fill && m->next.size>=maxsize+sizeof(blockmark_t)) {
*size = m->next.size;
return m;
}
m = (blockmark_t*)((uintptr_t)m + m->next.size);
}
return NULL;
}
static int getMaxFreeBlock(void* block)
{
// get start of block
blockmark_t *m = (blockmark_t*)((uintptr_t)block+MMAPSIZE-sizeof(blockmark_t)); // styart with the end
int maxsize = 0;
while(m->prev.x32) { // while there is a subblock
if(!m->prev.fill && m->prev.size>maxsize) {
maxsize = m->prev.size;
if((uintptr_t)block+maxsize>(uintptr_t)m)
return maxsize; // no block large enough left...
}
m = (blockmark_t*)((uintptr_t)m - m->prev.size);
}
return maxsize;
}
static void* allocBlock(void* block, void *sub, int size)
{
blockmark_t *s = (blockmark_t*)sub;
blockmark_t *n = (blockmark_t*)((uintptr_t)s + s->next.size);
s->next.fill = 1;
s->next.size = size+sizeof(blockmark_t);
blockmark_t *m = (blockmark_t*)((uintptr_t)s + s->next.size); // this is new n
m->prev.fill = 1;
m->prev.size = s->next.size;
if(n!=m) {
// new mark
m->prev.fill = 1;
m->prev.size = s->next.size;
m->next.fill = 0;
m->next.size = (uintptr_t)n - (uintptr_t)m;
n->prev.fill = 0;
n->prev.size = m->next.size;
}
return (void*)((uintptr_t)sub + sizeof(blockmark_t));
}
static void freeBlock(void *block, void* sub, int size)
{
blockmark_t *m = (blockmark_t*)block;
blockmark_t *s = (blockmark_t*)sub;
blockmark_t *n = (blockmark_t*)((uintptr_t)s + s->next.size);
if(block!=sub)
m = (blockmark_t*)((uintptr_t)s - s->prev.size);
s->next.fill = 0;
n->prev.fill = 0;
// check if merge with previous
if (s->prev.x32 && !s->prev.fill) {
// remove s...
m->next.size += s->next.size;
n->prev.size = m->next.size;
s = m;
}
// check if merge with next
if(n->next.x32 && !n->next.fill) {
blockmark_t *n2 = (blockmark_t*)((uintptr_t)n + n->next.size);
//remove n
s->next.size += n->next.size;
n2->prev.size = s->next.size;
}
}
uintptr_t FindFreeDynarecMap(dynablock_t* db, int size)
{
// look for free space
void* sub = NULL;
for(int i=0; i<my_context->mmapsize; ++i) {
if(my_context->mmaplist[i].maxfree>=size) {
int rsize = 0;
sub = getFirstBlock(my_context->mmaplist[i].block, size, &rsize);
if(sub) {
uintptr_t ret = (uintptr_t)allocBlock(my_context->mmaplist[i].block, sub, size);
if(rsize==my_context->mmaplist[i].maxfree)
my_context->mmaplist[i].maxfree = getMaxFreeBlock(my_context->mmaplist[i].block);
kh_dynablocks_t *blocks = my_context->mmaplist[i].dblist;
if(!blocks) {
blocks = my_context->mmaplist[i].dblist = kh_init(dynablocks);
kh_resize(dynablocks, blocks, 64);
}
++end;
khint_t k;
int r;
k = kh_put(dynablocks, blocks, (uintptr_t)db, &r);
kh_value(blocks, k) = db;
return ret;
}
if(size) *size = end-start;
return start;
}
++start;
}
return -1;
return 0;
}
static void allocBlock(mmaplist_t *map, int start, int size)
uintptr_t AddNewDynarecMap(dynablock_t* db, int size)
{
for(int i=0; i<size; ++i) {
map->map[start/8]|=(1<<(start&7));
++start;
}
}
static void freeBlock(mmaplist_t *map, int start, int size)
{
for(int i=0; i<size; ++i) {
map->map[start/8]&=~(1<<(start&7));
++start;
int i = my_context->mmapsize++; // yeah, useful post incrementation
dynarec_log(LOG_DEBUG, "Ask for DynaRec Block Alloc #%d\n", my_context->mmapsize);
my_context->mmaplist = (mmaplist_t*)realloc(my_context->mmaplist, my_context->mmapsize*sizeof(mmaplist_t));
void *p = NULL;
if(posix_memalign(&p, box86_pagesize, MMAPSIZE)) {
dynarec_log(LOG_INFO, "Cannot create memory map of %d byte for dynarec block #%d\n", MMAPSIZE, i);
--my_context->mmapsize;
return 0;
}
mprotect(p, MMAPSIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
my_context->mmaplist[i].block = p;
// setup marks
blockmark_t* m = (blockmark_t*)p;
m->prev.x32 = 0;
m->next.fill = 0;
m->next.size = MMAPSIZE-sizeof(blockmark_t);
m = (blockmark_t*)(p+MMAPSIZE-sizeof(blockmark_t));
m->next.x32 = 0;
m->prev.fill = 0;
m->prev.size = MMAPSIZE-sizeof(blockmark_t);
// alloc 1st block
uintptr_t sub = (uintptr_t)allocBlock(my_context->mmaplist[i].block, p, size);
my_context->mmaplist[i].maxfree = getMaxFreeBlock(my_context->mmaplist[i].block);
kh_dynablocks_t *blocks = my_context->mmaplist[i].dblist = kh_init(dynablocks);
kh_resize(dynablocks, blocks, 64);
khint_t k;
int ret;
k = kh_put(dynablocks, blocks, (uintptr_t)db, &ret);
kh_value(blocks, k) = db;
return sub;
}
uintptr_t AllocDynarecMap(int size, int nolinker)
void ActuallyFreeDynarecMap(dynablock_t* db, uintptr_t addr, int size)
{
if(size>MMAPSIZE) {
#ifdef USE_MMAP
void* p = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(p==MAP_FAILED) {
dynarec_log(LOG_INFO, "Cannot create dynamic map of %d bytes\n", size);
return 0;
if(!addr || !size)
return;
for(int i=0; i<my_context->mmapsize; ++i) {
if ((addr>(uintptr_t)my_context->mmaplist[i].block)
&& (addr<((uintptr_t)my_context->mmaplist[i].block+MMAPSIZE))) {
void* sub = (void*)(addr-sizeof(blockmark_t));
freeBlock(my_context->mmaplist[i].block, sub, size);
my_context->mmaplist[i].maxfree = getMaxFreeBlock(my_context->mmaplist[i].block);
kh_dynablocks_t *blocks = my_context->mmaplist[i].dblist;
if(blocks) {
khint_t k = kh_get(dynablocks, blocks, (uintptr_t)db);
if(k!=kh_end(blocks))
kh_del(dynablocks, blocks, k);
}
return;
}
#else
}
if(my_context->mmapsize)
dynarec_log(LOG_NONE, "Warning, block %p (size %d) not found in mmaplist for Free\n", (void*)addr, size);
}
dynablock_t* FindDynablockFromNativeAddress(void* addr)
{
// look in actual list
for(int i=0; i<my_context->mmapsize; ++i) {
if ((uintptr_t)addr>=(uintptr_t)my_context->mmaplist[i].block
&& ((uintptr_t)addr<(uintptr_t)my_context->mmaplist[i].block+MMAPSIZE))
return FindDynablockDynablocklist(addr, my_context->mmaplist[i].dblist);
}
// look in oversized
return FindDynablockDynablocklist(addr, my_context->dblist_oversized);
}
uintptr_t AllocDynarecMap(dynablock_t* db, int size)
{
if(!size)
return 0;
if(size>MMAPSIZE-2*sizeof(blockmark_t)) {
void *p = NULL;
if(posix_memalign(&p, box86_pagesize, size)) {
dynarec_log(LOG_INFO, "Cannot create dynamic map of %d bytes\n", size);
return 0;
}
mprotect(p, size, PROT_READ | PROT_WRITE | PROT_EXEC);
#endif
kh_dynablocks_t *blocks = my_context->dblist_oversized;
if(!blocks) {
blocks = my_context->dblist_oversized = kh_init(dynablocks);
kh_resize(dynablocks, blocks, 64);
}
khint_t k;
int ret;
k = kh_put(dynablocks, blocks, (uintptr_t)db, &ret);
kh_value(blocks, k) = db;
return (uintptr_t)p;
}
pthread_mutex_lock(&my_context->mutex_mmap);
int bsize = (size+MMAPBLOCK-1)/MMAPBLOCK;
// look for free space
for(int i=0; i<my_context->mmapsize; ++i) {
int rsize = 0;
int start = 0;
do {
start = getFirstBlock(my_context->mmaplist+i, start, bsize, &rsize);
if(start!=-1 && rsize>=bsize) {
allocBlock(my_context->mmaplist+i, start, bsize);
uintptr_t ret = (uintptr_t)my_context->mmaplist[i].block + start*MMAPBLOCK;
pthread_mutex_unlock(&my_context->mutex_mmap);
return ret;
}
if(start!=-1)
start += rsize;
} while (start!=-1);
if(pthread_mutex_trylock(&my_context->mutex_mmap)) {
sched_yield(); // give it a chance
if(pthread_mutex_trylock(&my_context->mutex_mmap))
return 0; // cannot lock, baillout
}
// no luck, add a new one !
int i = my_context->mmapsize++; // yeah, useful post incrementation
dynarec_log(LOG_DEBUG, "Ask for DynaRec Block Alloc #%d\n", my_context->mmapsize);
my_context->mmaplist = (mmaplist_t*)realloc(my_context->mmaplist, my_context->mmapsize*sizeof(mmaplist_t));
#ifdef USE_MMAP
void* p = mmap(NULL, MMAPSIZE, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if(p==MAP_FAILED) {
dynarec_log(LOG_INFO, "Cannot create memory map of %d byte for dynarec block #%d\n", MMAPSIZE, i);
--my_context->mmapsize;
pthread_mutex_unlock(&my_context->mutex_mmap);
return 0;
}
#else
void *p = NULL;
if(posix_memalign(&p, box86_pagesize, MMAPSIZE)) {
dynarec_log(LOG_INFO, "Cannot create memory map of %d byte for dynarec block #%d\n", MMAPSIZE, i);
--my_context->mmapsize;
pthread_mutex_unlock(&my_context->mutex_mmap);
return 0;
}
mprotect(p, MMAPSIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
#endif
my_context->mmaplist[i].block = p;
memset(my_context->mmaplist[i].map, 0, sizeof(my_context->mmaplist[i].map));
allocBlock(my_context->mmaplist+i, 0, bsize);
uintptr_t ret = FindFreeDynarecMap(db, size);
if(!ret)
ret = AddNewDynarecMap(db, size);
pthread_mutex_unlock(&my_context->mutex_mmap);
return (uintptr_t)p;
return ret;
}
void FreeDynarecMap(uintptr_t addr, uint32_t size)
void FreeDynarecMap(dynablock_t* db, uintptr_t addr, uint32_t size)
{
if(size>MMAPSIZE) {
munmap((void*)addr, size);
kh_dynablocks_t *blocks = my_context->dblist_oversized;
if(blocks) {
khint_t k = kh_get(dynablocks, blocks, (uintptr_t)db);
if(k!=kh_end(blocks))
kh_del(dynablocks, blocks, k);
}
return;
}
pthread_mutex_lock(&my_context->mutex_mmap);
int bsize = (size+MMAPBLOCK-1)/MMAPBLOCK;
// look for free space
for(int i=0; i<my_context->mmapsize; ++i) {
if(addr>=(uintptr_t)my_context->mmaplist[i].block && ((uintptr_t)my_context->mmaplist[i].block+MMAPSIZE)>=addr+size) {
int start = (addr - (uintptr_t)my_context->mmaplist[i].block) / MMAPBLOCK;
freeBlock(my_context->mmaplist+i, start, bsize);
pthread_mutex_unlock(&my_context->mutex_mmap);
return;
}
}
ActuallyFreeDynarecMap(db, addr, size);
pthread_mutex_unlock(&my_context->mutex_mmap);
}
// each dynmap is 64k of size
dynablocklist_t* getDBFromAddress(uintptr_t addr)
{
int idx = (addr>>DYNAMAP_SHIFT);
if(!my_context->dynmap[idx]) {
return NULL;
}
return my_context->dynmap[idx]->dynablocks;
}
void addDBFromAddressRange(uintptr_t addr, uintptr_t size, int nolinker)
void addDBFromAddressRange(box86context_t* context, uintptr_t addr, uintptr_t size, int nolinker)
{
dynarec_log(LOG_DEBUG, "addDBFromAddressRange %p -> %p\n", (void*)addr, (void*)(addr+size-1));
uintptr_t idx = (addr>>DYNAMAP_SHIFT);
uintptr_t end = ((addr+size-1)>>DYNAMAP_SHIFT);
for (uintptr_t i=idx; i<=end; ++i) {
if(!my_context->dynmap[i]) {
my_context->dynmap[i] = (dynmap_t*)calloc(1, sizeof(dynmap_t));
my_context->dynmap[i]->dynablocks = NewDynablockList(i<<DYNAMAP_SHIFT, i<<DYNAMAP_SHIFT, 1<<DYNAMAP_SHIFT, nolinker, 0);
} else {
ProtectkDynablockList(&my_context->dynmap[i]->dynablocks);
if(!context->dynmap[i]) {
context->dynmap[i] = NewDynablockList(i<<DYNAMAP_SHIFT, i<<DYNAMAP_SHIFT, 1<<DYNAMAP_SHIFT, nolinker, 0);
}
}
}
void cleanDBFromAddressRange(uintptr_t addr, uintptr_t size, int destroy)
void cleanDBFromAddressRange(box86context_t* context, uintptr_t addr, uintptr_t size, int destroy)
{
dynarec_log(LOG_DEBUG, "cleanDBFromAddressRange %p -> %p %s\n", (void*)addr, (void*)(addr+size-1), destroy?"destroy":"mark");
uintptr_t idx = (addr>box86_dynarec_largest && !destroy)?((addr-box86_dynarec_largest)>>DYNAMAP_SHIFT):(addr>>DYNAMAP_SHIFT);
uintptr_t end = ((addr+size-1)>>DYNAMAP_SHIFT);
for (uintptr_t i=idx; i<=end; ++i) {
dynmap_t* dynmap = my_context->dynmap[i];
if(dynmap) {
uintptr_t startdb = StartDynablockList(dynmap->dynablocks);
uintptr_t enddb = EndDynablockList(dynmap->dynablocks);
dynablocklist_t* dblist = context->dynmap[i];
if(dblist) {
uintptr_t startdb = StartDynablockList(dblist);
uintptr_t enddb = EndDynablockList(dblist);
uintptr_t startaddr = addr;
if(startaddr<startdb) startaddr = startdb;
uintptr_t endaddr = addr + size - 1;
if(endaddr>enddb) endaddr = enddb;
if(startaddr==startdb && endaddr==enddb) {
if(destroy) {
my_context->dynmap[i] = NULL;
FreeDynablockList(&dynmap->dynablocks);
free(dynmap);
context->dynmap[i] = NULL;
FreeDynablockList(&dblist);
} else
MarkDynablockList(&dynmap->dynablocks);
MarkDynablockList(&dblist);
} else
if(destroy)
FreeRangeDynablock(dynmap->dynablocks, startaddr, endaddr-startaddr+1);
FreeRangeDynablock(dblist, startaddr, endaddr-startaddr+1);
else
MarkRangeDynablock(dynmap->dynablocks, startaddr, endaddr-startaddr+1);
MarkRangeDynablock(dblist, startaddr, endaddr-startaddr+1);
}
}
@@ -231,7 +342,7 @@ void unprotectDB(uintptr_t addr, uintptr_t size)
uintptr_t end = (addr+size+(box86_pagesize-1))&~(box86_pagesize-1);
// should get "end" according to last block inside the window
mprotect((void*)start, end-start, PROT_READ|PROT_WRITE|PROT_EXEC);
cleanDBFromAddressRange(start, end-start, 0);
cleanDBFromAddressRange(my_context, start, end-start, 0);
}
#endif
@@ -245,17 +356,22 @@ void initAllHelpers(box86context_t* context)
my_context = context;
init_pthread_helper();
init_signal_helper(context);
#ifdef DYNAREC
if(box86_dynarec)
DynablockEmuMarker(context);
#endif
inited = 1;
}
EXPORTDYN
void finiAllHelpers()
void finiAllHelpers(box86context_t* context)
{
static int finied = 0;
if(finied)
return;
fini_pthread_helper();
fini_pthread_helper(context);
fini_signal_helper();
cleanAlternate();
finied = 1;
}
@@ -299,11 +415,19 @@ box86context_t *NewBox86Context(int argc)
#else
context->deferedInit = 1;
#endif
context->sel_serial = 1;
#ifdef DYNAREC
pthread_mutex_init(&context->mutex_blocks, NULL);
pthread_mutex_init(&context->mutex_mmap, NULL);
context->dynmap = (dynablocklist_t**)calloc(DYNAMAP_SIZE, sizeof(dynablocklist_t*));
#endif
context->maplib = NewLibrarian(context, 1);
context->local_maplib = NewLibrarian(context, 1);
context->system = NewBridge();
// create vsyscall
context->vsyscall = AddBridge(context->system, vFv, x86Syscall, 0);
context->vsyscall = AddBridge(context->system, context, vFv, x86Syscall, 0);
#ifdef BUILD_LIB
context->box86lib = RTLD_DEFAULT; // not ideal
#else
@@ -311,8 +435,6 @@ box86context_t *NewBox86Context(int argc)
#endif
context->dlprivate = NewDLPrivate();
context->callbacks = NewCallbackList();
context->argc = argc;
context->argv = (char**)calloc(context->argc+1, sizeof(char*));
@@ -329,11 +451,6 @@ box86context_t *NewBox86Context(int argc)
#endif
pthread_key_create(&context->tlskey, free_tlsdatasize);
#ifdef DYNAREC
pthread_mutex_init(&context->mutex_blocks, NULL);
pthread_mutex_init(&context->mutex_mmap, NULL);
context->dynablocks = NewDynablockList(0, 0, 0, 0, 0);
#endif
InitFTSMap(context);
for (int i=0; i<4; ++i) context->canary[i] = 1 + getrand(255);
@@ -390,19 +507,34 @@ void FreeBox86Context(box86context_t** context)
free(ctx->envv[i]);
free(ctx->envv);
if(ctx->atfork_sz) {
free(ctx->atforks);
ctx->atforks = NULL;
ctx->atfork_sz = ctx->atfork_cap = 0;
}
for(int i=0; i<MAX_SIGNAL; ++i)
if(ctx->signals[i]!=0 && ctx->signals[i]!=1) {
signal(i, SIG_DFL);
}
#ifdef DYNAREC
dynarec_log(LOG_DEBUG, "Free global Dynarecblocks\n");
if(ctx->dynablocks)
FreeDynablockList(&ctx->dynablocks);
for (int i=0; i<ctx->mmapsize; ++i)
for (int i=0; i<ctx->mmapsize; ++i) {
if(ctx->mmaplist[i].block)
#ifdef USE_MMAP
munmap(ctx->mmaplist[i].block, MMAPSIZE);
#else
free(ctx->mmaplist[i].block);
#endif
if(ctx->mmaplist[i].dblist) {
kh_destroy(dynablocks, ctx->mmaplist[i].dblist);
ctx->mmaplist[i].dblist = NULL;
}
}
if(ctx->dblist_oversized) {
kh_destroy(dynablocks, ctx->dblist_oversized);
ctx->dblist_oversized = NULL;
}
ctx->mmapsize = 0;
dynarec_log(LOG_DEBUG, "Free dynamic Dynarecblocks\n");
cleanDBFromAddressRange(0, 0xffffffff, 1);
cleanDBFromAddressRange(ctx, 0, 0xffffffff, 1);
pthread_mutex_destroy(&ctx->mutex_blocks);
pthread_mutex_destroy(&ctx->mutex_mmap);
free(ctx->mmaplist);
@@ -429,8 +561,6 @@ void FreeBox86Context(box86context_t** context)
freeGLProcWrapper(ctx);
freeALProcWrapper(ctx);
FreeCallbackList(&ctx->callbacks);
void* ptr;
if ((ptr = pthread_getspecific(ctx->tlskey)) != NULL) {
free_tlsdatasize(ptr);
@@ -458,25 +588,16 @@ void FreeBox86Context(box86context_t** context)
pthread_mutex_destroy(&ctx->mutex_thread);
#ifdef DYNAREC
pthread_mutex_destroy(&ctx->mutex_dyndump);
free(ctx->dynmap);
ctx->dynmap = NULL;
#endif
free_neededlib(&ctx->neededlibs);
if(ctx->atfork_sz) {
free(ctx->atforks);
ctx->atforks = NULL;
ctx->atfork_sz = ctx->atfork_cap = 0;
}
for(int i=0; i<MAX_SIGNAL; ++i)
if(ctx->signals[i]!=0 && ctx->signals[i]!=1) {
signal(i, SIG_DFL);
}
if(ctx->emu_sig)
FreeX86Emu(&ctx->emu_sig);
finiAllHelpers();
finiAllHelpers(ctx);
free(ctx);
}
@@ -500,6 +621,13 @@ int AddTLSPartition(box86context_t* context, int tlssize) {
context->tlsdata = realloc(context->tlsdata, context->tlssize);
memmove(context->tlsdata+tlssize, context->tlsdata, oldsize); // move to the top, using memmove as regions will probably overlap
memset(context->tlsdata, 0, tlssize); // fill new space with 0 (not mandatory)
// clean GS segment for current emu
if(my_context) {
ResetSegmentsCache(thread_get_emu());
if(!(++context->sel_serial))
++context->sel_serial;
}
return -context->tlssize; // negative offset
}
+1 -1
View File
@@ -3,6 +3,6 @@
#define BOX86_MAJOR 0
#define BOX86_MINOR 1
#define BOX86_REVISION 4
#define BOX86_REVISION 8
#endif //__BOX86_VERSION_H_
+56 -6
View File
@@ -210,6 +210,12 @@ Op is 20-27
// cmp.s dst, src1, src2, lsl #imm
#define CMPS_REG_LSL_IMM5(src1, src2, imm5) \
EMIT(0xe1500000 | ((0) << 12) | ((src1) << 16) | brLSL(imm5, src2) )
// cmp.cond.s dst, src1, src2, lsl #imm
#define CMPS_REG_LSL_IMM5_COND(cond, src1, src2, imm5) \
EMIT((cond) | 0x01500000 | ((0) << 12) | ((src1) << 16) | brLSL(imm5, src2) )
// cmp.s dst, src, #imm
#define CMPS_IMM8_COND(cond, src, imm8) \
EMIT((cond) | 0x03500000 | ((0) << 12) | ((src) << 16) | brIMM(imm8) )
// cmp.s dst, src, #imm
#define CMPS_IMM8(src, imm8) \
EMIT(0xe3500000 | ((0) << 12) | ((src) << 16) | brIMM(imm8) )
@@ -387,12 +393,14 @@ Op is 20-27
#define LDRH_REG(reg, addr, rm) EMIT(HWS_REG(c__, 1, 1, 0, 1, addr, reg, 0, 1, rm))
#define STRH_REG(reg, addr, rm) EMIT(HWS_REG(c__, 1, 1, 0, 0, addr, reg, 0, 1, rm))
#define LDRHAI_REG_LSL_IMM5(reg, addr, rm) EMIT(HWS_REG(c__, 0, 1, 0, 1, addr, reg, 0, 1, rm))
#define STRHAI_REG_LSL_IMM5(reg, addr, rm) EMIT(HWS_REG(c__, 0, 1, 0, 0, addr, reg, 0, 1, rm))
#define LDRHB_IMM8(reg, addr, imm8) EMIT(HWS_OFF(c__, 1, (((imm8)<0)?0:1), 1, 1, addr, reg, 0, 1, abs(imm8)))
#define LDRHA_IMM8(reg, addr, imm8) EMIT(HWS_OFF(c__, 0, (((imm8)<0)?0:1), 0, 1, addr, reg, 0, 1, abs(imm8)))
#define STRHB_IMM8(reg, addr, imm8) EMIT(HWS_OFF(c__, 1, (((imm8)<0)?0:1), 1, 0, addr, reg, 0, 1, abs(imm8)))
#define STRHA_IMM8(reg, addr, imm8) EMIT(HWS_OFF(c__, 0, (((imm8)<0)?0:1), 0, 0, addr, reg, 0, 1, abs(imm8)))
#define LDRHAI_REG_LSL_IMM5(reg, addr, rm) EMIT(HWS_REG(c__, 0, 1, 0, 1, addr, reg, 0, 1, rm))
#define STRHAI_REG_LSL_IMM5(reg, addr, rm) EMIT(HWS_REG(c__, 0, 1, 0, 0, addr, reg, 0, 1, rm))
#define LDRHB_IMM8(reg, addr, imm8) EMIT(HWS_OFF(c__, 1, (((imm8)<0)?0:1), 1, 1, addr, reg, 0, 1, abs(imm8)))
#define LDRHA_IMM8(reg, addr, imm8) EMIT(HWS_OFF(c__, 0, (((imm8)<0)?0:1), 0, 1, addr, reg, 0, 1, abs(imm8)))
#define STRHB_IMM8(reg, addr, imm8) EMIT(HWS_OFF(c__, 1, (((imm8)<0)?0:1), 1, 0, addr, reg, 0, 1, abs(imm8)))
#define STRHA_IMM8(reg, addr, imm8) EMIT(HWS_OFF(c__, 0, (((imm8)<0)?0:1), 0, 0, addr, reg, 0, 1, abs(imm8)))
#define PUSH16(reg, addr) EMIT(HWS_OFF(c__, 1, 0, 1, 0, addr, reg, 0, 1, 2))
#define POP16(reg, addr) EMIT(HWS_OFF(c__, 0, 1, 0, 1, addr, reg, 0, 1, 2))
// Mul Long construction
#define MULLONG(Cond, U, A, S, RdHi, RdLo, Rs, Rm) (Cond | 0b00001<<23 | (U)<<22 | (A)<<21 | (S)<<20 | (RdHi)<<16 | (RdLo)<<12 | (Rs)<<8 | 0b1001<<4 | (Rm))
@@ -431,6 +439,9 @@ Op is 20-27
#define SSAT_gen(cond, sat_imm, Rd, imm5, sh, Rn) (cond | 0b0110101<<21 | (sat_imm)<<16 | (Rd)<<12 | (imm5)<<7 | (sh)<<6 | 0b01<<4 | (Rn))
// Signed Staturate Rn to 2^(staturate_to-1) into Rd. Optionnaly shift left Rn before saturate
#define SSAT_REG_LSL_IMM5(Rd, saturate_to, Rn, shift) EMIT(SSAT_gen(c__, (saturate_to)-1, Rd, shift, 0, Rn))
// Signed Staturate Rn to 2^(staturate_to-1) into Rd. Optionnaly shift left Rn before saturate
#define SSAT_REG_LSL_IMM5_COND(cond, Rd, saturate_to, Rn, shift) EMIT(SSAT_gen((cond), (saturate_to)-1, Rd, shift, 0, Rn))
#define USAT_gen(cond, sat_imm, Rd, imm5, sh, Rn) (cond | 0b0110111<<21 | (sat_imm)<<16 | (Rd)<<12 | (imm5)<<7 | (sh)<<6 | 0b01<<4 | (Rn))
// Unsigned Staturate Rn to 2^(staturate_to-1) into Rd. Optionnaly shift left Rn before saturate
#define USAT_REG_LSL_IMM5(Rd, saturate_to, Rn, shift) EMIT(SSAT_gen(c__, (saturate_to), Rd, shift, 0, Rn))
@@ -704,6 +715,14 @@ Op is 20-27
#define VMOV_igen(i, D, imm3, Vd, cmode, Q, op, imm4) (0b1111<<28 | 0b001<<25 | (i)<<24 | 1<<23 | (D)<<22 | (imm3)<<16 | (Vd)<<12 | (cmode)<<8 | (Q)<<6 | (op)<<5 | 1<<4 | (imm4))
#define VMOV_8(Dd, imm) EMIT(VMOV_igen(((imm)>>7)&1, ((Dd)>>4)&1, ((imm)>>4)&7, (Dd)&15, 0b1110, 0, 0, (imm)&15))
#define VMOVQ_8(Dd, imm) EMIT(VMOV_igen(((imm)>>7)&1, ((Dd)>>4)&1, ((imm)>>4)&7, (Dd)&15, 0b1110, 1, 0, (imm)&15))
// Dd <= imm8 in high bits
#define VMOV_H32(Dd, imm8) EMIT(VMOV_igen(((imm8)>>7)&1, ((Dd)>>4)&1, ((imm8)>>4)&7, (Dd)&15, 0b0110, 0, 0, (imm8)&15))
// Dd <= imm8 in high bits
#define VMOV_H16(Dd, imm8) EMIT(VMOV_igen(((imm8)>>7)&1, ((Dd)>>4)&1, ((imm8)>>4)&7, (Dd)&15, 0b1010, 0, 0, (imm8)&15))
// Qd <= imm8 in high bits
#define VMOVQ_H32(Dd, imm8) EMIT(VMOV_igen(((imm8)>>7)&1, ((Dd)>>4)&1, ((imm8)>>4)&7, (Dd)&15, 0b0110, 1, 0, (imm8)&15))
// Qd <= imm8 in high bits
#define VMOVQ_H16(Dd, imm8) EMIT(VMOV_igen(((imm8)>>7)&1, ((Dd)>>4)&1, ((imm8)>>4)&7, (Dd)&15, 0b1010, 1, 0, (imm8)&15))
#define VLD1LANE_gen(D, Rn, Vd, size, index_align, Rm) (0b1111<<28 | 0b0100<<24 | 1<<23 | (D)<<22 | 0b10<<20 | (Rn)<<16 | (Vd)<<12 | (size)<<10 | (index_align)<<4 | (Rm))
#define VLD1LANE_8(Dd, Rn, index) EMIT(VLD1LANE_gen(((Dd)>>4)&1, Rn, (Dd)&15, 0, (index)<<1, 15))
@@ -768,6 +787,14 @@ Op is 20-27
#define VCEQ_F32(Dd, Dn, Dm) EMIT(VCEQ_F_gen(0, ((Dd)>>4)&1, (Dn)&15, (Dd)&15, ((Dn)>>4)&1, 0, ((Dm)>>4)&1, (Dm)&15))
#define VCEQQ_F32(Dd, Dn, Dm) EMIT(VCEQ_F_gen(0, ((Dd)>>4)&1, (Dn)&15, (Dd)&15, ((Dn)>>4)&1, 1, ((Dm)>>4)&1, (Dm)&15))
#define VCEQ_0_gen(D, size, Vd, F, Q, M, Vm) (0b1111<<28 | 0b0011<<24 | 1<<23 | (D)<<22 | 0b11<<20 | (size)<<18 | 0b01<<16 | (Vd)<<12 | (F)<<10 | 0b010<<7 | (Q)<<6 | (M)<<5 | (Vm))
#define VCEQ_0_8(Dd, Dm) EMIT(VCEQ_0_gen(((Dd)>>4)&1, 0, (Dd)&15, 0, 0, ((Dm)>>4)&1, (Dm)&15))
#define VCEQ_0_16(Dd, Dm) EMIT(VCEQ_0_gen(((Dd)>>4)&1, 1, (Dd)&15, 0, 0, ((Dm)>>4)&1, (Dm)&15))
#define VCEQ_0_32(Dd, Dm) EMIT(VCEQ_0_gen(((Dd)>>4)&1, 2, (Dd)&15, 0, 0, ((Dm)>>4)&1, (Dm)&15))
#define VCEQQ_0_8(Dd, Dm) EMIT(VCEQ_0_gen(((Dd)>>4)&1, 0, (Dd)&15, 0, 1, ((Dm)>>4)&1, (Dm)&15))
#define VCEQQ_0_16(Dd, Dm) EMIT(VCEQ_0_gen(((Dd)>>4)&1, 1, (Dd)&15, 0, 1, ((Dm)>>4)&1, (Dm)&15))
#define VCEQQ_0_32(Dd, Dm) EMIT(VCEQ_0_gen(((Dd)>>4)&1, 2, (Dd)&15, 0, 1, ((Dm)>>4)&1, (Dm)&15))
#define VCGT_I_gen(U, D, size, Vn, Vd, N, Q, M, Vm) (0b1111<<28 | 0b001<<25 | (U)<<24 | 0<<23 | (D)<<22 | (size)<<20 | (Vn)<<16 | (Vd)<<12 | 0b0011<<8 | (N)<<7 | (Q)<<6 | (M)<<5 | (Vm))
#define VCGT_U8(Dd, Dn, Dm) EMIT(VCGT_I_gen(1, ((Dd)>>4)&1, 0, (Dn)&15, (Dd)&15, ((Dn)>>4)&1, 0, ((Dm)>>4)&1, (Dm)&15))
#define VCGTQ_U8(Dd, Dn, Dm) EMIT(VCGT_I_gen(1, ((Dd)>>4)&1, 0, (Dn)&15, (Dd)&15, ((Dn)>>4)&1, 1, ((Dm)>>4)&1, (Dm)&15))
@@ -793,6 +820,15 @@ Op is 20-27
#define VCGE_F32(Dd, Dn, Dm) EMIT(VCGE_F_gen(((Dd)>>4)&1, 0, (Dn)&15, (Dd)&15, ((Dn)>>4)&1, 0, ((Dm)>>4)&1, (Dm)&15))
#define VCGEQ_F32(Dd, Dn, Dm) EMIT(VCGE_F_gen(((Dd)>>4)&1, 0, (Dn)&15, (Dd)&15, ((Dn)>>4)&1, 1, ((Dm)>>4)&1, (Dm)&15))
#define VCLT_0_gen(D, size, Vd, F, Q, M, Vm) (0b1111<<28 | 0b0011<<24 | 1<<23 | (D)<<22 | 0b11<<20 | (size)<<18 | 0b01<<16 | (Vd)<<12 | (F)<<10 | 0b100<<7 | (Q)<<6 | (M)<<5 | (Vm))
#define VCLT_0_8(Dd, Dm) EMIT(VCLT_0_gen(((Dd)>>4)&1, 0, (Dd)&15, 0, 0, ((Dm)>>4)&1, (Dm)&15))
#define VCLT_0_16(Dd, Dm) EMIT(VCLT_0_gen(((Dd)>>4)&1, 1, (Dd)&15, 0, 0, ((Dm)>>4)&1, (Dm)&15))
#define VCLT_0_32(Dd, Dm) EMIT(VCLT_0_gen(((Dd)>>4)&1, 2, (Dd)&15, 0, 0, ((Dm)>>4)&1, (Dm)&15))
#define VCLTQ_0_8(Dd, Dm) EMIT(VCLT_0_gen(((Dd)>>4)&1, 0, (Dd)&15, 0, 1, ((Dm)>>4)&1, (Dm)&15))
#define VCLTQ_0_16(Dd, Dm) EMIT(VCLT_0_gen(((Dd)>>4)&1, 1, (Dd)&15, 0, 1, ((Dm)>>4)&1, (Dm)&15))
#define VCLTQ_0_32(Dd, Dm) EMIT(VCLT_0_gen(((Dd)>>4)&1, 2, (Dd)&15, 0, 1, ((Dm)>>4)&1, (Dm)&15))
#define VSHR_gen(U, D, imm6, Vd, L, Q, M, Vm) (0b1111<<28 | 0b001<<25 | (U)<<24 | 1<<23 | (D)<<22 | (imm6)<<16 | (Vd)<<12 | (L)<<7 | (Q)<<6 | (M)<<5 | 1<<4 | (Vm))
#define VSHR_U8(Dd, Dm, imm3) EMIT(VSHR_gen(1, ((Dd)>>4)&1, 0b001<<3 | (8-(imm3)), (Dd)&15, 0, 0, ((Dm)>>4)&1, (Dm)&15))
#define VSHR_S8(Dd, Dm, imm3) EMIT(VSHR_gen(0, ((Dd)>>4)&1, 0b001<<3 | (8-(imm3)), (Dd)&15, 0, 0, ((Dm)>>4)&1, (Dm)&15))
@@ -1161,4 +1197,18 @@ Op is 20-27
#define VQRDMULHQ_S16(Dd, Dn, Dm) EMIT(VQRDMULH_gen(((Dd)>>4)&1, 0b01, (Dn)&15, (Dd)&15, ((Dn)>>4)&1, 1, ((Dm)>>4)&1, (Dm)&15))
#define VQRDMULHQ_S32(Dd, Dn, Dm) EMIT(VQRDMULH_gen(((Dd)>>4)&1, 0b10, (Dn)&15, (Dd)&15, ((Dn)>>4)&1, 1, ((Dm)>>4)&1, (Dm)&15))
#define VDUP_sgen(D, imm4, Vd, Q, M, Vm) (0b1111<<28 | 0b0011<<24 | 1<<23 | (D)<<22 | 0b11<<20 | (imm4)<<16 | (Vd)<<12 | 0b1100<<8 | (Q)<<6 | (M)<<5 | (Vm))
// Dd <= Dup(Dm[x])
#define VDUP_32(Dd, Dm, x) EMIT(VDUP_sgen(((Dd)>>4)&1, (((x)<<3)|0b100), (Dd)&15, 0, ((Dm)>>4)&1, (Dm)&15))
#define VABS_vgen(D, size, Vd, F, Q, M, Vm) (0b1111<<28 | 0b0011<<24 | 1<<23 | (D)<<22 | 0b11<<20 | (size)<<18 | 0b01<<16 | (Vd)<<12 | (F)<<10 | 0b110<<7 | (Q)<<6 | (M)<<5 | (Vm))
#define VABS_S32(Dd, Dm) EMIT(VABS_vgen(((Dd)>>4)&1, 2, (Dd)&15, 0, 0, ((Dm)>>4)&1, (Dm)&15))
#define VABS_S16(Dd, Dm) EMIT(VABS_vgen(((Dd)>>4)&1, 1, (Dd)&15, 0, 0, ((Dm)>>4)&1, (Dm)&15))
#define VABS_S8(Dd, Dm) EMIT(VABS_vgen(((Dd)>>4)&1, 0, (Dd)&15, 0, 0, ((Dm)>>4)&1, (Dm)&15))
#define VABS_F(Dd, Dm) EMIT(VABS_vgen(((Dd)>>4)&1, 2, (Dd)&15, 1, 0, ((Dm)>>4)&1, (Dm)&15))
#define VABSQ_S32(Dd, Dm) EMIT(VABS_vgen(((Dd)>>4)&1, 2, (Dd)&15, 0, 1, ((Dm)>>4)&1, (Dm)&15))
#define VABSQ_S16(Dd, Dm) EMIT(VABS_vgen(((Dd)>>4)&1, 1, (Dd)&15, 0, 1, ((Dm)>>4)&1, (Dm)&15))
#define VABSQ_S8(Dd, Dm) EMIT(VABS_vgen(((Dd)>>4)&1, 0, (Dd)&15, 0, 1, ((Dm)>>4)&1, (Dm)&15))
#define VABSQ_F(Dd, Dm) EMIT(VABS_vgen(((Dd)>>4)&1, 2, (Dd)&15, 1, 1, ((Dm)>>4)&1, (Dm)&15))
#endif //__ARM_EMITTER_H__
+39 -1
View File
@@ -7,10 +7,15 @@
.global arm_lock_read_b
.global arm_lock_write_b
.global arm_lock_read_h
.global arm_lock_write_h
.global arm_lock_read_d
.global arm_lock_write_d
.global arm_lock_read_dd
.global arm_lock_write_dd
.global arm_lock_xchg
.global arm_lock_storeifnull
arm_lock_read_b:
// address is r0, return is r0
@@ -23,6 +28,17 @@ arm_lock_write_b:
strexb r0, r1, [r2]
bx lr
arm_lock_read_h:
// address is r0, return is r0
ldrexh r0, [r0]
bx lr
arm_lock_write_h:
// address is r0, value is r1, return is r0
mov r2, r0
strexh r0, r1, [r2]
bx lr
arm_lock_read_d:
// address is r0, return is r0
// r0 needs to be aligned
@@ -48,4 +64,26 @@ arm_lock_write_dd:
// r0 needs to be aligned
strexd r3, r0, r1, [r2]
mov r0, r3
bx lr
bx lr
arm_lock_xchg:
// address is r0, value is r1, return old value in r0
// r0 needs to be aligned
ldrex r2, [r0]
strex r3, r1, [r0]
cmp r3, #1
beq arm_lock_xchg
mov r0, r2
bx lr
arm_lock_storeifnull:
// address is r0, value is r1, r1 store to r0 only if [r0] is 0. return new [r0] value (so r1 or old value)
// r0 needs to be aligned
ldrex r2, [r0]
cmp r2, #0
moveq r2, r1
strex r3, r2, [r0]
cmp r3, #1
beq arm_lock_storeifnull
mov r0, r2
bx lr
+11
View File
@@ -7,6 +7,11 @@ extern uint8_t arm_lock_read_b(void* addr);
// STREXB of ADDR, return 0 if ok, 1 if not
extern int arm_lock_write_b(void* addr, uint8_t val);
// LDREXH of ADDR
extern uint16_t arm_lock_read_h(void* addr);
// STREXH of ADDR, return 0 if ok, 1 if not
extern int arm_lock_write_h(void* addr, uint16_t val);
// LDREX of ADDR
extern uint32_t arm_lock_read_d(void* addr);
// STREX of ADDR, return 0 if ok, 1 if not
@@ -17,4 +22,10 @@ extern void arm_lock_read_dd(uint32_t* a, uint32_t* b, void* addr);
// STREX of ADDR, return 0 if ok, 1 if not
extern int arm_lock_write_dd(uint32_t a, uint32_t b, void* addr);
// Atomicaly exchange value at [p] with val, return old p
extern uintptr_t arm_lock_xchg(void* p, uintptr_t val);
// Atomicaly store value to [p] only if [p] is NULL. Return new [p] value (so val or old)
extern void* arm_lock_storeifnull(void*p, void* val);
#endif //__ARM_LOCK_HELPER__H__
+113 -348
View File
@@ -20,6 +20,7 @@
#include "elfloader.h"
#ifdef ARM
#include "dynarec_arm.h"
#include "arm_lock_helper.h"
#else
#error Unsupported architecture!
#endif
@@ -28,8 +29,6 @@
KHASH_MAP_INIT_INT(dynablocks, dynablock_t*)
KHASH_SET_INIT_INT(mark)
uint32_t X31_hash_code(void* addr, int len)
{
if(!len) return 0;
@@ -41,13 +40,15 @@ uint32_t X31_hash_code(void* addr, int len)
dynablocklist_t* NewDynablockList(uintptr_t base, uintptr_t text, int textsz, int nolinker, int direct)
{
if(!textsz) {
printf_log(LOG_NONE, "Error, creating a NULL sized Dynablock\n");
return NULL;
}
dynablocklist_t* ret = (dynablocklist_t*)calloc(1, sizeof(dynablocklist_t));
ret->blocks = (nolinker && direct)?NULL:kh_init(dynablocks);
ret->base = base;
ret->text = text;
ret->textsz = textsz;
ret->nolinker = nolinker;
pthread_rwlock_init(&ret->rwlock_blocks, NULL);
if(direct && textsz) {
ret->direct = (dynablock_t**)calloc(textsz, sizeof(dynablock_t*));
if(!ret->direct) {printf_log(LOG_NONE, "Warning, fail to create direct block for dynablock @%p\n", (void*)text);}
@@ -58,8 +59,11 @@ dynablocklist_t* NewDynablockList(uintptr_t base, uintptr_t text, int textsz, in
void FreeDynablock(dynablock_t* db)
{
if(db) {
dynarec_log(LOG_DEBUG, "FreeDynablock(%p), db->block=%p x86=%p:%p father=%p, tablesz=%d, %swith %d son(s)\n", db, db->block, db->x86_addr, db->x86_addr+db->x86_size, db->father, db->tablesz, db->marks?"with marks, ":"", db->sons_size);
dynarec_log(LOG_DEBUG, "FreeDynablock(%p), db->block=%p x86=%p:%p father=%p, tablesz=%d, with %d son(s) already gone=%d\n", db, db->block, db->x86_addr, db->x86_addr+db->x86_size, db->father, db->tablesz, db->sons_size, db->gone);
if(db->gone)
return; // already in the process of deletion!
db->done = 0;
db->gone = 1;
// remove from direct if there
uintptr_t startdb = db->parent->text;
uintptr_t enddb = db->parent->text + db->parent->textsz;
@@ -68,53 +72,19 @@ void FreeDynablock(dynablock_t* db)
if(addr>=startdb && addr<enddb)
db->parent->direct[addr-startdb] = NULL;
}
if(db->marks) {
// Follow mark and set arm_linker instead
khint_t k;
kh_foreach_key(db->marks, k,
void** p = (void**)(uintptr_t)k;
dynarec_log(LOG_DEBUG, " -- resettable(%p)\n", p);
resettable(p);
);
// free mark
kh_destroy(mark, db->marks);
db->marks = NULL;
}
for(int i=0; i<db->tablesz; i+=4) {
dynablock_t* p = (dynablock_t*)db->table[i+3];
dynarec_log(LOG_DEBUG, " -- table[%d+3] = %p ", i, p);
if(p && p!=db && p->marks) {
khint_t kd = kh_get(mark, p->marks, (uintptr_t)(&db->table[i+0]));
if(kd!=kh_end(p->marks)) {
kh_del(mark, p->marks, kd);
dynarec_log(LOG_DEBUG, "cleaned");
}
else {dynarec_log(LOG_DEBUG, "not found");}
}
dynarec_log(LOG_DEBUG, "\n");
}
// remove from hash if there
if (db->parent->blocks) {
pthread_rwlock_wrlock(&db->parent->rwlock_blocks);
khint_t kdb;
kdb = kh_get(dynablocks, db->parent->blocks, (uintptr_t) db->x86_addr - db->parent->base);
if(kdb!=kh_end(db->parent->blocks))
kh_del(dynablocks, db->parent->blocks, kdb);
pthread_rwlock_unlock(&db->parent->rwlock_blocks);
}
// remove and free the sons
for (int i=0; i<db->sons_size; ++i) {
dynablock_t *son = db->sons[i];
db->sons[i] = NULL;
dynablock_t *son = (dynablock_t*)arm_lock_xchg(&db->sons[i], 0);
FreeDynablock(son);
}
// only the father free the DynarecMap
if(!db->father) {
dynarec_log(LOG_DEBUG, " -- FreeDyrecMap(%p, %d)\n", db->block, db->size);
FreeDynarecMap((uintptr_t)db->block, db->size);
FreeDynarecMap(db, (uintptr_t)db->block, db->size);
}
free(db->sons);
free(db->table);
free(db->instsize);
free(db);
}
}
@@ -125,21 +95,7 @@ void FreeDynablockList(dynablocklist_t** dynablocks)
return;
if(!*dynablocks)
return;
dynarec_log(LOG_DEBUG, "Free %d Blocks from Dynablocklist (with %d buckets, nolinker=%d) %s\n", (*dynablocks)->blocks?kh_size((*dynablocks)->blocks):0, (*dynablocks)->blocks?kh_n_buckets((*dynablocks)->blocks):0, (*dynablocks)->nolinker, ((*dynablocks)->direct)?" With Direct mapping enabled":"");
dynablock_t* db;
if((*dynablocks)->blocks) {
// create a list of the parent db to delete (because there are sons in the middle that will be invalid if father is removed)
dynablock_t** list = (dynablock_t**)calloc(kh_size((*dynablocks)->blocks), sizeof(dynablock_t*));
int n = 0;
kh_foreach_value((*dynablocks)->blocks, db,
if(!db->father) list[n++] = db;
);
for (int i=0; i<n; ++i)
FreeDynablock(list[i]);
kh_destroy(dynablocks, (*dynablocks)->blocks);
(*dynablocks)->blocks = NULL;
free(list);
}
dynarec_log(LOG_DEBUG, "Free Direct Blocks %p from Dynablocklist nolinker=%d\n", (*dynablocks)->direct, (*dynablocks)->nolinker);
if((*dynablocks)->direct) {
for (int i=0; i<(*dynablocks)->textsz; ++i) {
if((*dynablocks)->direct[i] && !(*dynablocks)->direct[i]->father)
@@ -147,8 +103,7 @@ void FreeDynablockList(dynablocklist_t** dynablocks)
}
free((*dynablocks)->direct);
}
(*dynablocks)->direct = 0;
pthread_rwlock_destroy(&(*dynablocks)->rwlock_blocks);
(*dynablocks)->direct = NULL;
free(*dynablocks);
*dynablocks = NULL;
@@ -159,17 +114,8 @@ void MarkDynablock(dynablock_t* db)
if(db) {
if(db->father)
db = db->father; // mark only father
if(db->marks && !db->need_test) {
// Follow mark and set arm_linker instead
khint_t k;
kh_foreach_key(db->marks, k,
void** p = (void**)(uintptr_t)k;
resettable(p);
);
// free mark
kh_clear(mark, db->marks);
}
db->need_test = 1;
if(db->nolinker)
db->need_test = 1; // test only blocks that can be marked (and so deleted)
}
}
@@ -182,43 +128,6 @@ void ProtectDynablock(dynablock_t* db)
}
}
void RemoveMark(void** table)
{
// remove old value if any
dynablock_t *old = (dynablock_t*)table[3];
if(old && old->father)
old = old->father;
if(old && old->marks) {
khint_t kd = kh_get(mark, old->marks, (uintptr_t)table);
if(kd!=kh_end(old->marks))
kh_del(mark, old->marks, kd);
}
table[3] = NULL;
}
// source is linked to dest (i.e. source->table[x] = dest->block), so add a "mark" in dest, add a "linked" info to source
void AddMark(dynablock_t* source, dynablock_t* dest, void** table)
{
int ret;
// remove old value if any
dynablock_t *old = (dynablock_t*)table[3];
if(old && old->father)
old = old->father;
if(old && old->marks) {
khint_t kd = kh_get(mark, old->marks, (uintptr_t)table);
if(kd!=kh_end(old->marks))
kh_del(mark, old->marks, kd);
}
// add mark if needed
if(dest->father)
dest = dest->father;
if(dest->marks) {
kh_put(mark, dest->marks, (uintptr_t)table, &ret);
table[3] = (void*)dest;
} else
table[3] = NULL;
}
void MarkDynablockList(dynablocklist_t** dynablocks)
{
if(!dynablocks)
@@ -227,36 +136,30 @@ void MarkDynablockList(dynablocklist_t** dynablocks)
return;
if(!(*dynablocks)->nolinker)
return;
dynarec_log(LOG_DEBUG, "Marked %d Blocks from Dynablocklist (with %d buckets, nolinker=%d) %p:0x%x %s\n", (*dynablocks)->blocks?(kh_size((*dynablocks)->blocks)):0, (*dynablocks)->blocks?(kh_n_buckets((*dynablocks)->blocks)):0, (*dynablocks)->nolinker, (void*)(*dynablocks)->text, (*dynablocks)->textsz, ((*dynablocks)->direct)?" With Direct mapping enabled":"");
dynarec_log(LOG_DEBUG, "Marked Blocks from Dynablocklist nolinker=%d %p:0x%x\n", (*dynablocks)->nolinker, (void*)(*dynablocks)->text, (*dynablocks)->textsz);
dynablock_t* db;
if((*dynablocks)->blocks) {
kh_foreach_value((*dynablocks)->blocks, db,
MarkDynablock(db);
);
}
if((*dynablocks)->direct) {
for (int i=0; i<(*dynablocks)->textsz; ++i) {
MarkDynablock((*dynablocks)->direct[i]);
db = (*dynablocks)->direct[i];
if(db)
MarkDynablock(db);
}
}
}
void ProtectkDynablockList(dynablocklist_t** dynablocks)
void ProtectDynablockList(dynablocklist_t** dynablocks)
{
if(!dynablocks)
return;
if(!*dynablocks)
return;
dynarec_log(LOG_DEBUG, "Protect %d Blocks from Dynablocklist (with %d buckets, nolinker=%d) %p:0x%x %s\n", (*dynablocks)->blocks?(kh_size((*dynablocks)->blocks)):0, (*dynablocks)->blocks?(kh_n_buckets((*dynablocks)->blocks)):0, (*dynablocks)->nolinker, (void*)(*dynablocks)->text, (*dynablocks)->textsz, ((*dynablocks)->direct)?" With Direct mapping enabled":"");
dynarec_log(LOG_DEBUG, "Protect Blocks from Dynablocklist nolinker=%d %p:0x%x\n", (*dynablocks)->nolinker, (void*)(*dynablocks)->text, (*dynablocks)->textsz);
dynablock_t* db;
if((*dynablocks)->blocks) {
kh_foreach_value((*dynablocks)->blocks, db,
ProtectDynablock(db);
);
}
if((*dynablocks)->direct) {
for (int i=0; i<(*dynablocks)->textsz; ++i) {
ProtectDynablock((*dynablocks)->direct[i]);
db = (*dynablocks)->direct[i];
if(db)
ProtectDynablock(db);
}
}
}
@@ -270,7 +173,7 @@ uintptr_t StartDynablockList(dynablocklist_t* db)
uintptr_t EndDynablockList(dynablocklist_t* db)
{
if(db)
return db->text+db->textsz;
return db->text+db->textsz-1;
return 0;
}
void MarkDirectDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size)
@@ -315,26 +218,12 @@ void FreeRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t s
if(!dynablocks)
return;
if(dynablocks->blocks || dynablocks->direct) {
if(dynablocks->direct) {
dynablock_t* db;
uintptr_t s, e;
int ret;
khint_t k;
kh_dynablocks_t *blocks = kh_init(dynablocks);
// copy in a temporary list
if(dynablocks->blocks) {
kh_foreach_value(dynablocks->blocks, db,
if(db->father)
db =db->father;
s = (uintptr_t)db->x86_addr;
e = (uintptr_t)db->x86_addr+db->x86_size-1;
if((s>=addr && s<(addr+size)) || (e>=addr && e<(addr+size))) {
//ProtectDynablock(db);
k = kh_put(dynablocks, blocks, (uintptr_t)db, &ret);
kh_value(blocks, k) = db;
}
);
}
if(dynablocks->direct) {
uintptr_t startdb = dynablocks->text;
uintptr_t enddb = startdb + dynablocks->textsz;
@@ -345,14 +234,15 @@ void FreeRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t s
if(end>enddb)
end = enddb;
if(end>startdb && start<enddb)
for(uintptr_t i = start; i<end; ++i)
if(dynablocks->direct[i-startdb]) {
db = dynablocks->direct[i-startdb];
for(uintptr_t i = start; i<end; ++i) {
db = (dynablock_t*)arm_lock_xchg(&dynablocks->direct[i-startdb], 0);
if(db) {
if(db->father)
db =db->father;
db = db->father;
k = kh_put(dynablocks, blocks, (uintptr_t)db, &ret);
kh_value(blocks, k) = db;
}
}
}
// purge the list
kh_foreach_value(blocks, db,
@@ -369,154 +259,45 @@ void MarkRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t s
return;
if(dynablocks->direct)
MarkDirectDynablock(dynablocks, addr, size);
if(dynablocks->blocks) {
dynablock_t* db;
uintptr_t s, e;
kh_foreach_value(dynablocks->blocks, db,
s = (uintptr_t)db->x86_addr;
e = (uintptr_t)db->x86_addr+db->x86_size-1;
if((s>=addr && s<(addr+size)) || (e>=addr && e<(addr+size)))
MarkDynablock(db);
);
}
}
dynablock_t* FindDynablockDynablocklist(void* addr, dynablocklist_t* dynablocks)
dynablock_t* FindDynablockDynablocklist(void* addr, kh_dynablocks_t* dynablocks)
{
if(!dynablocks)
return NULL;
if(dynablocks->direct)
for(int i=0; i<dynablocks->textsz; ++i) {
dynablock_t* db;
if((db = dynablocks->direct[i])) {
uintptr_t s = (uintptr_t)db->block;
uintptr_t e = (uintptr_t)db->block+db->size;
if((uintptr_t)addr>=s && (uintptr_t)addr<e)
return db->father?db->father:db;
}
}
if(dynablocks->blocks) {
dynablock_t* db;
uintptr_t s, e;
kh_foreach_value(dynablocks->blocks, db,
s = (uintptr_t)db->block;
e = (uintptr_t)db->block+db->size;
if((uintptr_t)addr>=s && (uintptr_t)addr<e)
return db->father?db->father:db;
);
}
dynablock_t* db;
kh_foreach_value(dynablocks, db,
uintptr_t s = (uintptr_t)db->block;
uintptr_t e = (uintptr_t)db->block+db->size;
if((uintptr_t)addr>=s && (uintptr_t)addr<e)
return db->father?db->father:db;
)
return NULL;
}
dynablock_t* FindDynablockFromNativeAddress(void* addr)
static dynablocklist_t* getDBFromAddress(uintptr_t addr)
{
// unoptimized search through all dynablockslist for the dynablock that contains native addr (NULL if not found)
// search "volatile" dynarec first
dynablock_t *ret = NULL;
for(int idx=0; idx<DYNAMAP_SIZE && !ret; ++idx)
if(my_context->dynmap[idx])
ret = FindDynablockDynablocklist(addr, my_context->dynmap[idx]->dynablocks);
if(ret)
return ret;
// last, search context dynablocks
if(my_context->dynablocks)
ret = FindDynablockDynablocklist(addr, my_context->dynablocks);
return ret;
const int idx = (addr>>DYNAMAP_SHIFT);
return (my_context->dynmap[idx])?my_context->dynmap[idx]:NULL;
}
void ConvertHash2Direct(dynablocklist_t* dynablocks)
{
if(dynablocks->textsz==0 || dynablocks->text==0 || !dynablocks->blocks)
return; // nothing to do
// create the new set
dynablock_t **direct = (dynablock_t**)calloc(dynablocks->textsz, sizeof(dynablock_t*));
kh_dynablocks_t *blocks = kh_init(dynablocks);
// transfert
int ret;
khint_t k;
dynablock_t* db;
uintptr_t key;
uintptr_t start = dynablocks->text;
uintptr_t end = start + dynablocks->textsz;
kh_foreach(dynablocks->blocks, key, db,
key += dynablocks->base;
if(key>=start && key<end)
direct[key-start] = db;
else {
k = kh_put(dynablocks, blocks, key-dynablocks->base, &ret);
if(ret) { // don't try to insert if already done...
kh_value(blocks, k) = db;
}
}
);
// destroy old and do the swap (should swap before destroy, but hash access is always behind mutex)
kh_destroy(dynablocks, dynablocks->blocks);
dynablocks->blocks = NULL;
dynablocks->direct = direct;
// unlock
pthread_rwlock_unlock(&dynablocks->rwlock_blocks);
// move the one that doesn't fit to other dynablocks
// first check if everything can be moved
int ok = 1;
kh_foreach(blocks, key, db,
key += dynablocks->base;
dynablocklist_t *newdbs = getDBFromAddress(key); // will crash if no dynablocks is found
if(!newdbs)
ok = 0;
else {
if(newdbs->direct) {
if(newdbs->direct[key-newdbs->text])
ok = 0;
} else {
khint_t k;
pthread_rwlock_rdlock(&newdbs->rwlock_blocks);
k = kh_get(dynablocks, newdbs->blocks, key-newdbs->base);
if(k!=kh_end(newdbs->blocks))
ok = 0;
pthread_rwlock_unlock(&newdbs->rwlock_blocks);
}
}
);
if(ok) {
kh_foreach(blocks, key, db,
key += dynablocks->base;
dynablocklist_t *newdbs = getDBFromAddress(key); // will crash if no dynablocks is found
if(newdbs->direct) {
newdbs->direct[key-newdbs->text] = db;
} else {
khint_t k;
int ret;
pthread_rwlock_wrlock(&newdbs->rwlock_blocks);
k = kh_put(dynablocks, newdbs->blocks, key-newdbs->base, &ret);
kh_value(newdbs->blocks, k) = db;
pthread_rwlock_unlock(&newdbs->rwlock_blocks);
}
);
kh_destroy(dynablocks, blocks);
} else {
pthread_rwlock_wrlock(&dynablocks->rwlock_blocks);
dynablocks->blocks = blocks;
dynarec_log(LOG_DEBUG, "Cannot convert dynablocks(%p) to pure direct\n", (void*)dynablocks->text);
}
}
// a block is 4096 byte, so get a low magic size or no block will get "direct" treatment
#define MAGIC_SIZE 8
#define MAGIC_SIZE2 16
dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int with_marks, int* created)
dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* created)
{
if(!dynablocks) {
dynarec_log(LOG_INFO, "Warning: Ask to create a dynblock with a NULL dynablocklist (addr=%p)\n", (void*)addr);
dynarec_log(LOG_INFO, "Warning: Ask to create a dynablock with a NULL dynablocklist (addr=%p)\n", (void*)addr);
*created = 0;
return NULL;
}
khint_t k;
int ret;
if((addr<dynablocks->text) || (addr>=(dynablocks->text+dynablocks->textsz))) {
// this should be useless
//dynarec_log(LOG_INFO, "Warning: Refused to create a Direct Block that is out-of-bound: dynablocks=%p (%p:%p), addr=%p\n", dynablocks, (void*)(dynablocks->text), (void*)(dynablocks->text+dynablocks->textsz), (void*)addr);
//*created = 0;
//return NULL;
return AddNewDynablock(getDBFromAddress(addr), addr, created);
}
dynablock_t* block = NULL;
// first, check if it exist in direct access mode
if(dynablocks->direct && (addr>=dynablocks->text) && (addr<(dynablocks->text+dynablocks->textsz))) {
if(dynablocks->direct) {
block = dynablocks->direct[addr-dynablocks->text];
if(block) {
dynarec_log(LOG_DUMP, "Block already exist in Direct Map\n");
@@ -525,65 +306,25 @@ dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int wi
}
}
if(dynablocks->blocks) {
pthread_rwlock_rdlock(&dynablocks->rwlock_blocks);
// check again, in case it's been converted to direct in another thread
if(dynablocks->blocks) {
// check if the block exist
khint_t k;
k = kh_get(dynablocks, dynablocks->blocks, addr-dynablocks->base);
if(k!=kh_end(dynablocks->blocks)) {
block = kh_value(dynablocks->blocks, k);
pthread_rwlock_unlock(&dynablocks->rwlock_blocks);
dynarec_log(LOG_DUMP, "Block already exist in Hash Map\n");
*created = 0;
return block;
}
}
pthread_rwlock_unlock(&dynablocks->rwlock_blocks);
}
if (!*created)
return block;
// Lock as write now!
if(dynablocks->blocks)
pthread_rwlock_wrlock(&dynablocks->rwlock_blocks);
if(!dynablocks->direct)
dynablocks->direct = (dynablock_t**)calloc(dynablocks->textsz, sizeof(dynablock_t*));
// create and add new block
dynarec_log(LOG_DUMP, "Ask for DynaRec Block creation @%p\n", (void*)addr);
if(dynablocks->direct && (addr>=dynablocks->text) && (addr<(dynablocks->text+dynablocks->textsz))) {
block = dynablocks->direct[addr-dynablocks->text] = (dynablock_t*)calloc(1, sizeof(dynablock_t));
} else {
if(dynablocks->textsz && ((addr<dynablocks->text) || (addr>=(dynablocks->text+dynablocks->textsz)))) {
if(dynablocks->blocks)
pthread_rwlock_unlock(&dynablocks->rwlock_blocks);
//dynarec_log(LOG_INFO, "Warning: Refused to create a Direct Block that is out-of-bound: dynablocks=%p (%p:%p), addr=%p\n", dynablocks, (void*)(dynablocks->text), (void*)(dynablocks->text+dynablocks->textsz), (void*)addr);
//*created = 0;
//return NULL;
return AddNewDynablock(getDBFromAddress(addr), addr, with_marks, created);
}
k = kh_put(dynablocks, dynablocks->blocks, addr-dynablocks->base, &ret);
if(!ret) {
// Ooops, block is already there? retreive it and bail out
dynarec_log(LOG_DUMP, "Block already exist in Hash Map\n");
block = kh_value(dynablocks->blocks, k);
if(dynablocks->blocks)
pthread_rwlock_unlock(&dynablocks->rwlock_blocks);
*created = 0;
return block;
}
block = kh_value(dynablocks->blocks, k) = (dynablock_t*)calloc(1, sizeof(dynablock_t));
// check if size of hash map == magic size, if yes, convert to direct before unlocking
if(!dynablocks->direct && dynablocks->textsz && kh_size(dynablocks->blocks)>=MAGIC_SIZE && kh_size(dynablocks->blocks)<(MAGIC_SIZE2))
ConvertHash2Direct(dynablocks);
}
block->parent = dynablocks;
// add mark if needed
if(with_marks)
block->marks = kh_init(mark);
// create an empty block first, so if other thread want to execute the same block, they can, but using interpretor path
if(dynablocks->blocks)
pthread_rwlock_unlock(&dynablocks->rwlock_blocks);
block = (dynablock_t*)calloc(1, sizeof(dynablock_t));
dynablock_t* tmp = (dynablock_t*)arm_lock_storeifnull(&dynablocks->direct[addr-dynablocks->text], block);
if(tmp != block) {
// a block appeard!
free(block);
*created = 0;
return tmp;
}
block->parent = dynablocks;
*created = 1;
return block;
@@ -593,65 +334,89 @@ dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int wi
return NULL if block is not found / cannot be created.
Don't create if create==0
*/
static dynablock_t* internalDBGetBlock(x86emu_t* emu, uintptr_t addr, int create, dynablock_t* current)
static dynablock_t* internalDBGetBlock(x86emu_t* emu, uintptr_t addr, uintptr_t filladdr, int create, dynablock_t* current)
{
// try the quickest way first: get parent of current and check if ok!
dynablocklist_t *dynablocks = NULL;
dynablock_t* block = NULL;
if(current) {
dynablocks = current->parent;
if(!(addr>=dynablocks->text && addr<(dynablocks->text+dynablocks->textsz)))
dynablocks = current->parent;
if(dynablocks && !(addr>=dynablocks->text && addr<(dynablocks->text+dynablocks->textsz)))
dynablocks = NULL;
else if(dynablocks->direct && (addr>=dynablocks->text) && (addr<(dynablocks->text+dynablocks->textsz))) {
block = dynablocks->direct[addr-dynablocks->text];
if(block)
return block;
}
}
// nope, lets do the long way
if(!dynablocks)
dynablocks = GetDynablocksFromAddress(emu->context, addr);
if(!dynablocks)
return NULL;
if(!dynablocks) {
dynablocks = getDBFromAddress(addr);
if(!dynablocks) {
dynablocks = GetDynablocksFromAddress(emu->context, addr);
if(!dynablocks)
return NULL;
}
}
// check direct first, without lock
if(dynablocks->direct && (addr>=dynablocks->text) && (addr<(dynablocks->text+dynablocks->textsz)))
block = dynablocks->direct[addr-dynablocks->text];
if(block)
return block;
if(dynablocks->direct/* && (addr>=dynablocks->text) && (addr<(dynablocks->text+dynablocks->textsz))*/)
if((block = dynablocks->direct[addr-dynablocks->text]))
return block;
int created = create;
block = AddNewDynablock(dynablocks, addr, (dynablocks->nolinker)&&(dynablocks->direct), &created);
if(!created || !create)
block = AddNewDynablock(dynablocks, addr, &created);
if(!created)
return block; // existing block...
if(box86_dynarec_dump)
pthread_mutex_lock(&my_context->mutex_dyndump);
// fill the block
block->x86_addr = (void*)addr;
FillBlock(block);
if(!FillBlock(block, filladdr)) {
dynablocks->direct[addr-dynablocks->text] = NULL;
free(block);
block = NULL;
}
if(box86_dynarec_dump)
pthread_mutex_unlock(&my_context->mutex_dyndump);
dynarec_log(LOG_DEBUG, " --- DynaRec Block %s @%p:%p (%p, 0x%x bytes, %swith %d son(s))\n", created?"created":"recycled", (void*)addr, (void*)(addr+block->x86_size), block->block, block->size, block->marks?"with Marks, ":"", block->sons_size);
dynarec_log(LOG_DEBUG, " --- DynaRec Block %s @%p:%p (%p, 0x%x bytes, with %d son(s))\n", created?"created":"recycled", (void*)addr, (void*)(addr-((block)?block->x86_size:0)), (block)?block->block:0, (block)?block->size:0, (block)?block->sons_size:0);
return block;
}
dynablock_t* DBGetBlock(x86emu_t* emu, uintptr_t addr, int create, dynablock_t** current)
{
dynablock_t *db = internalDBGetBlock(emu, addr, create, *current);
dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, *current);
if(db && (db->need_test || (db->father && db->father->need_test))) {
dynablock_t *father = db->father?db->father:db;
uint32_t hash = father->nolinker?X31_hash_code(father->x86_addr, father->x86_size):0;
if(hash!=father->hash) {
dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X)%s with %d son(s)\n", father, father->x86_addr, father->x86_addr+father->x86_size, hash, father->hash, father->marks?" with Mark,":"", father->sons_size);
dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) with %d son(s)\n", father, father->x86_addr, father->x86_addr+father->x86_size, hash, father->hash, father->sons_size);
// no more current if it gets invalidated too
if(*current && father->x86_addr>=(*current)->x86_addr && (father->x86_addr+father->x86_size)<(*current)->x86_addr)
*current = NULL;
// Free father, it's now invalid!
FreeDynablock(father);
// start again... (will create a new block)
db = internalDBGetBlock(emu, addr, create, *current);
db = internalDBGetBlock(emu, addr, addr, create, *current);
} else {
father->need_test = 0;
protectDB((uintptr_t)father->x86_addr, father->x86_size);
}
}
return db;
}
dynablock_t* DBAlternateBlock(x86emu_t* emu, uintptr_t addr, uintptr_t filladdr)
{
dynarec_log(LOG_DEBUG, "Creating AlternateBlock at %p for %p\n", (void*)addr, (void*)filladdr);
int create = 1;
dynablock_t *db = internalDBGetBlock(emu, addr, filladdr, create, NULL);
if(db && (db->need_test || (db->father && db->father->need_test))) {
dynablock_t *father = db->father?db->father:db;
uint32_t hash = father->nolinker?X31_hash_code(father->x86_addr, father->x86_size):0;
if(hash!=father->hash) {
dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) with %d son(s)\n", father, father->x86_addr, father->x86_addr+father->x86_size, hash, father->hash, father->sons_size);
// Free father, it's now invalid!
FreeDynablock(father);
// start again... (will create a new block)
db = internalDBGetBlock(emu, addr, filladdr, create, NULL);
} else {
father->need_test = 0;
protectDB((uintptr_t)father->x86_addr, father->x86_size);
+12 -10
View File
@@ -2,36 +2,38 @@
#define __DYNABLOCK_PRIVATE_H_
typedef struct dynablocklist_s dynablocklist_t;
typedef struct kh_dynablocks_s kh_dynablocks_t;
typedef struct kh_mark_s kh_mark_t;
typedef struct instsize_s {
unsigned int x86:4;
unsigned int nat:4;
} instsize_t;
typedef struct dynablock_s {
dynablocklist_t* parent;
kh_mark_t* marks; // List of blocks that marked this block
void* block;
int size;
void* x86_addr;
int x86_size;
uint32_t hash;
int need_test;
uintptr_t* table;
int tablesz;
int done;
uint8_t need_test;
uint8_t done;
uint8_t gone;
uint8_t nolinker;
int isize;
dynablock_t** sons; // sons (kind-of dummy dynablock...)
int sons_size;
dynablock_t* father; // set only in the case of a son
int nolinker;
instsize_t* instsize;
} dynablock_t;
typedef struct dynablocklist_s {
kh_dynablocks_t *blocks;
pthread_rwlock_t rwlock_blocks;
uintptr_t base;
uintptr_t text;
int textsz;
uintptr_t base;
int nolinker; // in case this dynablock can disapear (also, block memory are allocated with a temporary scheme)
dynablock_t **direct; // direct mapping (waste of space, so not always there)
dynablock_t** direct; // direct mapping (waste of space, so not always there)
} dynablocklist_t;
#endif //__DYNABLOCK_PRIVATE_H_
+21 -18
View File
@@ -56,18 +56,15 @@ void* UpdateLinkTable(x86emu_t* emu, void** table, uintptr_t addr)
dynablock_t* current = (dynablock_t*)table[2];
if(current->father)
current = current->father;
void * jblock;
dynablock_t* block = DBGetBlock(emu, addr, 1, &current);
if(!current) { // current has been invalidated, stop running it...
//dynarec_log(LOG_DEBUG, "--- Current invalidated while linking.\n");
return arm_epilog_fast;
}
if(table[3]) {
//dynarec_log(LOG_DEBUG, "--- Remove mark from %p (%p)\n", current, table[3]);
RemoveMark(table);
}
if(!block) {
// no block, don't try again, ever
tableupdate(arm_epilog, addr, table);
// no block, let link table as is...
//tableupdate(arm_epilog, addr, table);
return arm_epilog_fast;
}
if(!block->done) {
@@ -75,20 +72,18 @@ void* UpdateLinkTable(x86emu_t* emu, void** table, uintptr_t addr)
//tableupdate(arm_linker, addr, table);
return arm_epilog_fast;
}
if(!block->block) {
if(!(jblock=block->block)) {
// null block, but done: go to epilog, no linker here
tableupdate(arm_epilog, addr, table);
return arm_epilog_fast;
}
dynablock_t *father = block->father?block->father:block;
if(!block->parent->nolinker || (current && father->marks)) {
//dynablock_t *father = block->father?block->father:block;
if(!block->parent->nolinker) {
//dynarec_log(LOG_DEBUG, "--- Linking %p/%p to %p (table=%p[%p/%p/%p/%p])\n", block, block->block, current, table, table[0], table[1], table[2], table[3]);
// only update block if linker is allowed or if marks is possibe
if(current && father->marks && current!=father)
AddMark(current, father, table);
tableupdate(block->block, addr, table);
// only update block if linker is allowed
tableupdate(jblock, addr, table);
}
return block->block;
return jblock;
}
#endif
@@ -103,7 +98,10 @@ void DynaCall(x86emu_t* emu, uintptr_t addr)
ejb->emu = emu;
ejb->jmpbuf_ok = 1;
jmpbuf_reset = 1;
setjmp((struct __jmp_buf_tag*)ejb->jmpbuf);
if(setjmp((struct __jmp_buf_tag*)ejb->jmpbuf)) {
printf_log(LOG_DEBUG, "Setjmp DynaCall, fs=0x%x\n", ejb->emu->segs[_FS]);
addr = R_EIP; // not sure if it should still be inside DynaCall!
}
}
}
#ifdef DYNAREC
@@ -149,7 +147,10 @@ void DynaCall(x86emu_t* emu, uintptr_t addr)
ejb->emu = emu;
ejb->jmpbuf_ok = 1;
jmpbuf_reset = 1;
setjmp((struct __jmp_buf_tag*)ejb->jmpbuf);
if(setjmp((struct __jmp_buf_tag*)ejb->jmpbuf)) {
printf_log(LOG_DEBUG, "Setjmp inner DynaCall, fs=0x%x\n", ejb->emu->segs[_FS]);
addr = R_EIP;
}
}
}
}
@@ -183,7 +184,8 @@ int DynaRun(x86emu_t* emu)
ejb->emu = emu;
ejb->jmpbuf_ok = 1;
jmpbuf_reset = 1;
setjmp((struct __jmp_buf_tag*)ejb->jmpbuf);
if(setjmp((struct __jmp_buf_tag*)ejb->jmpbuf))
printf_log(LOG_DEBUG, "Setjmp DynaRun, fs=0x%x\n", ejb->emu->segs[_FS]);
}
}
#ifdef DYNAREC
@@ -219,7 +221,8 @@ int DynaRun(x86emu_t* emu)
ejb->emu = emu;
ejb->jmpbuf_ok = 1;
jmpbuf_reset = 1;
setjmp((struct __jmp_buf_tag*)ejb->jmpbuf);
if(setjmp((struct __jmp_buf_tag*)ejb->jmpbuf))
printf_log(LOG_DEBUG, "Setjmp inner DynaRun, fs=0x%x\n", ejb->emu->segs[_FS]);
}
}
}
+64 -8
View File
@@ -159,14 +159,42 @@ uint32_t needed_flags(dynarec_arm_t *dyn, int ninst, uint32_t setf, int recurse)
return needed;
}
instsize_t* addInst(instsize_t* insts, size_t* size, size_t* cap, int x86_size, int arm_size)
{
// x86 instruction is <16 bytes
int toadd;
if(x86_size>arm_size)
toadd = 1 + x86_size/15;
else
toadd = 1 + arm_size/15;
if((*size)+toadd>(*cap)) {
*cap = (*size)+toadd;
insts = (instsize_t*)realloc(insts, (*cap)*sizeof(instsize_t));
}
while(toadd) {
if(x86_size>15)
insts[*size].x86 = 15;
else
insts[*size].x86 = x86_size;
x86_size -= insts[*size].x86;
if(arm_size>15)
insts[*size].nat = 15;
else
insts[*size].nat = arm_size;
arm_size -= insts[*size].nat;
++(*size);
--toadd;
}
return insts;
}
void arm_pass0(dynarec_arm_t* dyn, uintptr_t addr);
void arm_pass1(dynarec_arm_t* dyn, uintptr_t addr);
void arm_pass2(dynarec_arm_t* dyn, uintptr_t addr);
void arm_pass3(dynarec_arm_t* dyn, uintptr_t addr);
void* FillBlock(dynablock_t* block) {
void* FillBlock(dynablock_t* block, uintptr_t addr) {
// init the helper
uintptr_t addr = (uintptr_t)block->x86_addr;
dynarec_arm_t helper = {0};
helper.nolinker = box86_dynarec_linker?(block->parent->nolinker):1;
helper.start = addr;
@@ -212,11 +240,12 @@ void* FillBlock(dynablock_t* block) {
arm_pass2(&helper, addr);
// ok, now allocate mapped memory, with executable flag on
int sz = helper.arm_size;
void* p = (void*)AllocDynarecMap(sz, block->parent->nolinker);
void* p = (void*)AllocDynarecMap(block, sz);
if(p==NULL) {
dynarec_log(LOG_DEBUG, "AllocDynarecMap(%p, %d) failed, cancelling block\n", block, sz);
free(helper.insts);
free(helper.next);
return (void*)block;
return NULL;
}
helper.block = p;
helper.arm_start = (uintptr_t)p;
@@ -235,9 +264,32 @@ void* FillBlock(dynablock_t* block) {
}
helper.arm_size = 0;
arm_pass3(&helper, addr);
if(sz!=helper.arm_size) {printf_log(LOG_NONE, "BOX86: Warning, size difference in block between pass2 (%d) & pass3 (%d)!\n", sz, helper.arm_size);}
if(sz!=helper.arm_size) {
printf_log(LOG_NONE, "BOX86: Warning, size difference in block between pass2 (%d) & pass3 (%d)!\n", sz, helper.arm_size);
uint8_t *dump = (uint8_t*)helper.start;
printf_log(LOG_NONE, "Dump of %d x86 opcodes:\n", helper.size);
for(int i=0; i<helper.size; ++i) {
printf_log(LOG_NONE, "%p:", dump);
for(; dump<(uint8_t*)helper.insts[i+1].x86.addr; ++dump)
printf_log(LOG_NONE, " %02X", *dump);
printf_log(LOG_NONE, "\t%d -> %d\n", helper.insts[i].size2, helper.insts[i].size);
}
printf_log(LOG_NONE, " ------------\n");
}
// all done...
__clear_cache(p, p+sz); // need to clear the cache before execution...
// keep size of instructions for signal handling
{
size_t cap = 1;
for(int i=0; i<helper.size; ++i)
cap += 1 + ((helper.insts[i].x86.size>helper.insts[i].size)?helper.insts[i].x86.size:helper.insts[i].size)/15;
size_t size = 0;
block->instsize = (instsize_t*)calloc(cap, sizeof(instsize_t));
for(int i=0; i<helper.size; ++i)
block->instsize = addInst(block->instsize, &size, &cap, helper.insts[i].x86.size, helper.insts[i].size/4);
block->instsize = addInst(block->instsize, &size, &cap, 0, 0); // add a "end of block" mark, just in case
}
// ok, free the helper now
free(helper.insts);
free(helper.next);
block->table = helper.table;
@@ -249,7 +301,7 @@ void* FillBlock(dynablock_t* block) {
block->block = p;
block->nolinker = helper.nolinker;
block->need_test = 0;
block->x86_addr = (void*)start;
//block->x86_addr = (void*)start;
block->x86_size = end-start;
if(box86_dynarec_largest<block->x86_size)
box86_dynarec_largest = block->x86_size;
@@ -261,8 +313,8 @@ void* FillBlock(dynablock_t* block) {
sons = (dynablock_t**)calloc(helper.sons_size, sizeof(dynablock_t*));
for (int i=0; i<helper.sons_size; ++i) {
int created = 1;
dynablock_t *son = AddNewDynablock(block->parent, helper.sons_x86[i], 0, &created);
if(created) { // avoid breaking a working block! also, block could be outside this parent...
dynablock_t *son = AddNewDynablock(block->parent, helper.sons_x86[i], &created);
if(created || !son->parent) { // avoid breaking a working block! also, block could be outside this parent...
son->block = helper.sons_arm[i];
son->x86_addr = (void*)helper.sons_x86[i];
son->x86_size = end-helper.sons_x86[i];
@@ -270,6 +322,8 @@ void* FillBlock(dynablock_t* block) {
son->father = block;
son->done = 1;
sons[sons_size++] = son;
if(!son->parent)
son->parent = block->parent;
}
}
if(sons_size) {
@@ -280,6 +334,8 @@ void* FillBlock(dynablock_t* block) {
}
if(block->parent->nolinker)
protectDB((uintptr_t)block->x86_addr, block->x86_size);
free(helper.sons_x86);
free(helper.sons_arm);
block->done = 1;
return (void*)block;
}
+103 -61
View File
@@ -26,8 +26,6 @@
uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog)
{
uint8_t nextop, opcode;
uintptr_t natcall;
int retn;
uint8_t gd, ed;
int8_t i8;
int32_t i32, j32, tmp;
@@ -105,7 +103,7 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
POP(xESP, 1<<x2);
STRH_REG(x2, xEmu, x1);
MOVW(x1, 0);
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_clean[_ES]));
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_serial[_ES]));
break;
case 0x08:
INST_NAME("OR Eb, Gb");
@@ -283,7 +281,7 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
POP(xESP, 1<<x2);
STRH_REG(x2, xEmu, x1);
MOVW(x1, 0);
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_clean[_DS]));
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_serial[_DS]));
break;
case 0x20:
INST_NAME("AND Eb, Gb");
@@ -1158,7 +1156,7 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
STRH_IMM8(ed, x2, 0);
}
MOVW(x1, 0);
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_clean[(nextop&0x38)>>3]));
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_serial[(nextop&0x38)>>3]));
break;
case 0x8F:
INST_NAME("POP Ed");
@@ -1550,7 +1548,8 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
case 0xC2:
INST_NAME("RETN");
SETFLAGS(X_ALL, SF_SET); // Hack, set all flags (to an unknown state...)
//SETFLAGS(X_ALL, SF_SET); // Hack, set all flags (to an unknown state...)
READFLAGS(X_PEND); // lets play safe here too
BARRIER(2);
i32 = F16;
retn_to_epilog(dyn, ninst, i32);
@@ -1624,6 +1623,7 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
*need_epilog = 1;
} else {
MESSAGE(LOG_DUMP, "Native Call to %s\n", GetNativeName(GetNativeFnc(ip)));
x87_forget(dyn, ninst, x3, x12, 0);
MOV32(x12, ip+1); // read the 0xCC
addr+=4+4;
STM(xEmu, (1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10)|(1<<11)|(1<<12));
@@ -1953,7 +1953,7 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
UBFX(x1, xEAX, 0, 16); // load AX
u8 = F8;
MOVW(x2, u8);
CALL_(aam16, x1, 0);
CALL_(aad16, x1, 0);
BFI(xEAX, x1, 0, 16);
break;
case 0xD6:
@@ -2046,64 +2046,102 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
case 0xE8:
INST_NAME("CALL Id");
SETFLAGS(X_ALL, SF_SET); // Hack to set flags to "dont'care" state
i32 = F32S;
if(addr+i32==0) {
#if STEP == 3
printf_log(LOG_NONE, "Warning, jump to 0x0 at %p (%p)\n", (void*)addr, (void*)(addr-1));
printf_log(LOG_NONE, "Warning, CALL to 0x0 at %p (%p)\n", (void*)addr, (void*)(addr-1));
#endif
}
if(isNativeCall(dyn, addr+i32, &natcall, &retn)) {
BARRIER(1);
BARRIER_NEXT(1);
MOV32(x2, addr);
PUSH(xESP, 1<<x2);
MESSAGE(LOG_DUMP, "Native Call to %s (retn=%d)\n", GetNativeName(GetNativeFnc(natcall-1)), retn);
// calling a native function
MOV32(x12, natcall); // read the 0xCC
STM(xEmu, (1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10)|(1<<11)|(1<<12));
CALL_(x86Int3, -1, 0);
LDM(xEmu, (1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10)|(1<<11)|(1<<12));
MOV32(x3, natcall+2+4+4);
CMPS_REG_LSL_IMM5(xEIP, x3, 0);
B_MARK(cNE); // Not the expected address, exit dynarec block
POP(xESP, (1<<xEIP)); // pop the return address
if(retn) {
ADD_IMM8(xESP, xESP, retn);
}
MOV32(x3, addr);
CMPS_REG_LSL_IMM5(xEIP, x3, 0);
B_MARK(cNE); // Not the expected address again
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, quit));
CMPS_IMM8(x1, 1);
B_NEXT(cNE); // not quitting, so lets continue
MARK;
jump_to_epilog(dyn, 0, xEIP, ninst);
} else if ((i32==0) && ((PK(0)>=0x58) && (PK(0)<=0x5F))) {
MESSAGE(LOG_DUMP, "Hack for Call 0, Pop reg\n");
u8 = F8;
gd = xEAX+(u8&7);
MOV32(gd, addr-1);
} else if (((addr+i32)>0x10000) && (PK(i32+0)==0x8B) && (((PK(i32+1))&0xC7)==0x04) && (PK(i32+2)==0x24) && (PK(i32+3)==0xC3)) {
MESSAGE(LOG_DUMP, "Hack for Call x86.get_pc_thunk.reg\n");
u8 = PK(i32+1);
gd = xEAX+((u8&0x38)>>3);
MOV32(gd, addr);
} else {
// regular call
BARRIER(1);
BARRIER_NEXT(1);
if(!dyn->nolinker && (!dyn->insts || ninst!=dyn->size-1)) {
PASS2(cstack_push(dyn, ninst, addr, dyn->insts[ninst+1].address, x1, x2);)
//cstatck_push put addr in x2, don't need to put it again
} else {
PASS2(cstack_push(dyn, ninst, 0, 0, x1, x2);)
*need_epilog = 0;
*ok = 0;
#if STEP == 0
if ((i32==0) && ((PK(0)>=0x58) && (PK(0)<=0x5F)))
tmp = 1;
else if (((addr+i32)>0x10000) && (PK(i32+0)==0x8B) && (((PK(i32+1))&0xC7)==0x04) && (PK(i32+2)==0x24) && (PK(i32+3)==0xC3))
tmp = 2;
else if(isNativeCall(dyn, addr+i32, NULL, NULL))
tmp = 3;
else
tmp = 0;
#elif STEP < 2
if ((i32==0) && ((PK(0)>=0x58) && (PK(0)<=0x5F)))
tmp = dyn->insts[ninst].pass2choice = 1;
else if (((addr+i32)>0x10000) && (PK(i32+0)==0x8B) && (((PK(i32+1))&0xC7)==0x04) && (PK(i32+2)==0x24) && (PK(i32+3)==0xC3))
tmp = dyn->insts[ninst].pass2choice = 2;
else if(isNativeCall(dyn, addr+i32, &dyn->insts[ninst].natcall, &dyn->insts[ninst].retn))
tmp = dyn->insts[ninst].pass2choice = 3;
else
tmp = dyn->insts[ninst].pass2choice = 0;
#else
tmp = dyn->insts[ninst].pass2choice;
#endif
switch(tmp) {
case 1:
//SETFLAGS(X_ALL, SF_SET); // Hack to set flags to "dont'care" state
MESSAGE(LOG_DUMP, "Hack for Call 0, Pop reg\n");
u8 = F8;
gd = xEAX+(u8&7);
MOV32(gd, addr-1);
break;
case 2:
SETFLAGS(X_ALL, SF_SET); // Hack to set flags to "dont'care" state
MESSAGE(LOG_DUMP, "Hack for Call x86.get_pc_thunk.reg\n");
u8 = PK(i32+1);
gd = xEAX+((u8&0x38)>>3);
MOV32(gd, addr);
break;
case 3:
SETFLAGS(X_ALL, SF_SET); // Hack to set flags to "dont'care" state
BARRIER(1);
BARRIER_NEXT(1);
MOV32(x2, addr);
}
PUSH(xESP, 1<<x2);
jump_to_linker(dyn, addr+i32, 0, ninst);
PUSH(xESP, 1<<x2);
MESSAGE(LOG_DUMP, "Native Call to %s (retn=%d)\n", GetNativeName(GetNativeFnc(dyn->insts[ninst].natcall-1)), dyn->insts[ninst].retn);
// calling a native function
x87_forget(dyn, ninst, x3, x12, 0);
MOV32(x12, dyn->insts[ninst].natcall); // read the 0xCC already
STM(xEmu, (1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10)|(1<<11)|(1<<12));
CALL_(x86Int3, -1, 0);
LDM(xEmu, (1<<4)|(1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<9)|(1<<10)|(1<<11)|(1<<12));
MOV32(x3, dyn->insts[ninst].natcall+2+4+4);
CMPS_REG_LSL_IMM5(xEIP, x3, 0);
B_MARK(cNE); // Not the expected address, exit dynarec block
POP(xESP, (1<<xEIP)); // pop the return address
if(dyn->insts[ninst].retn) {
ADD_IMM8(xESP, xESP, dyn->insts[ninst].retn);
}
MOV32(x3, addr);
CMPS_REG_LSL_IMM5(xEIP, x3, 0);
B_MARK(cNE); // Not the expected address again
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, quit));
CMPS_IMM8(x1, 1);
B_NEXT(cNE); // not quitting, so lets continue
MARK;
jump_to_epilog(dyn, 0, xEIP, ninst);
break;
default:
if(ninst && dyn->insts && dyn->insts[ninst-1].x86.set_flags) {
READFLAGS(X_PEND); // that's suspicious
} else {
SETFLAGS(X_ALL, SF_SET); // Hack to set flags to "dont'care" state
}
// regular call
BARRIER(1);
BARRIER_NEXT(1);
if(!dyn->nolinker && (!dyn->insts || ninst!=dyn->size-1)) {
PASS2(cstack_push(dyn, ninst, addr, dyn->insts[ninst+1].address, x1, x2);)
//cstatck_push put addr in x2, don't need to put it again
} else {
PASS2(cstack_push(dyn, ninst, 0, 0, x1, x2);)
*need_epilog = 0;
*ok = 0;
MOV32(x2, addr);
}
PUSH(xESP, 1<<x2);
if(addr+i32==0) { // self modifying code maybe? so use indirect address fetching
MOV32(x12, addr-4);
LDR_IMM9(x12, x12, 0);
}
jump_to_linker(dyn, addr+i32, (addr+i32)?0:x12, ninst);
break;
}
break;
case 0xE9:
@@ -2118,7 +2156,7 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
}
JUMP(addr+i32);
if(dyn->insts) {
if(dyn->insts[ninst].x86.jmp_insts==-1) {
PASS2IF(dyn->insts[ninst].x86.jmp_insts==-1, 1) {
// out of the block
jump_to_linker(dyn, addr+i32, 0, ninst);
} else {
@@ -2624,7 +2662,11 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
break;
case 2: // CALL Ed
INST_NAME("CALL Ed");
SETFLAGS(X_ALL, SF_SET); //Hack to put flag in "don't care" state
PASS2IF(ninst && dyn->insts && dyn->insts[ninst-1].x86.set_flags, 1) {
READFLAGS(X_PEND); // that's suspicious
} else {
SETFLAGS(X_ALL, SF_SET); //Hack to put flag in "don't care" state
}
GETEDH(xEIP);
BARRIER(1);
BARRIER_NEXT(1);
+79 -5
View File
@@ -80,6 +80,7 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
#endif
switch(opcode) {
case 0x0B:
INST_NAME("UD2");
SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
@@ -1404,7 +1405,7 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
POP(xESP, 1<<x2);
STRH_REG(x2, xEmu, x1);
MOVW(x1, 0);
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_clean[_FS]));
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_serial[_FS]));
break;
case 0xA2:
INST_NAME("CPUID");
@@ -1467,7 +1468,7 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
POP(xESP, 1<<x2);
STRH_REG(x2, xEmu, x1);
MOVW(x1, 0);
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_clean[_GS]));
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_serial[_GS]));
break;
case 0xAB:
@@ -1711,6 +1712,37 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
AND_IMM8(x1, ed, 1);
STR_IMM9(x1, xEmu, offsetof(x86emu_t, flags[F_CF]));
break;
case 5:
INST_NAME("BTS Ed, Ib");
SETFLAGS(X_CF, SF_SUBSET);
gd = x2;
if((nextop&0xC0)==0xC0) {
ed = xEAX+(nextop&7);
u8 = F8;
MOVW(gd, u8);
wback = 0;
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, 4095, 0);
u8 = F8;
MOVW(gd, u8);
UBFX(x1, gd, 5, 3); // r1 = (gd>>5);
ADD_REG_LSL_IMM5(x3, ed, x1, 2); //(&ed)+=r1*4;
LDR_IMM9(x1, x3, fixedaddress);
ed = x1;
wback = x3;
}
AND_IMM8(x2, gd, 0x1f);
MOV_REG_LSR_REG(x12, ed, x2);
ANDS_IMM8(x12, x12, 1);
STR_IMM9(x12, xEmu, offsetof(x86emu_t, flags[F_CF]));
B_MARK3(cNE); // bit already set, jump to next instruction
MOVW(x12, 1);
XOR_REG_LSL_REG(ed, ed, x12, x2);
if(wback) {
STR_IMM9(ed, wback, fixedaddress);
}
MARK3;
break;
case 6:
INST_NAME("BTR Ed, Ib");
SETFLAGS(X_CF, SF_SUBSET);
@@ -1742,6 +1774,36 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
}
MARK3;
break;
case 7:
INST_NAME("BTC Ed, Ib");
SETFLAGS(X_CF, SF_SUBSET);
gd = x2;
if((nextop&0xC0)==0xC0) {
ed = xEAX+(nextop&7);
u8 = F8;
MOVW(gd, u8);
wback = 0;
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, 4095, 0);
u8 = F8;
MOVW(gd, u8);
UBFX(x1, gd, 5, 3); // r1 = (gd>>5);
ADD_REG_LSL_IMM5(x3, ed, x1, 2); //(&ed)+=r1*4;
LDR_IMM9(x1, x3, fixedaddress);
ed = x1;
wback = x3;
}
AND_IMM8(x2, gd, 0x1f);
MOV_REG_LSR_REG(x12, ed, x2);
ANDS_IMM8(x12, x12, 1);
STR_IMM9(x12, xEmu, offsetof(x86emu_t, flags[F_CF]));
MOVW_COND(cEQ, x12, 1); // may already 0x01
XOR_REG_LSL_REG(ed, ed, x12, x2);
if(wback) {
STR_IMM9(ed, wback, fixedaddress);
}
MARK3;
break;
default:
DEFAULT;
}
@@ -2096,7 +2158,13 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
GETEM(d1);
VQSUB_U16(d0, d0, d1);
break;
case 0xDA:
INST_NAME("PMINUB Gm, Em");
nextop = F8;
GETGM(d0);
GETEM(d1);
VMIN_U8(d0, d0, d1);
break;
case 0xDB:
INST_NAME("PAND Gm, Em");
nextop = F8;
@@ -2118,7 +2186,13 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
GETEM(d1);
VQADD_U16(d0, d0, d1);
break;
case 0xDE:
INST_NAME("PMAXUB Gm, Em");
nextop = F8;
GETGM(d0);
GETEM(d1);
VMAX_U8(d0, d0, d1);
break;
case 0xDF:
INST_NAME("PANDN Gm, Em");
nextop = F8;
@@ -2210,7 +2284,7 @@ uintptr_t dynarec0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
VQADD_S16(d0, d0, d1);
break;
case 0xEE:
INST_NAME("PMAXPS Gm, Em");
INST_NAME("PMAXSW Gm, Em");
nextop = F8;
GETGM(d0);
GETEM(d1);
+49 -1
View File
@@ -34,6 +34,7 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
MAYUSE(j32);
switch(opcode) {
case 0x03:
INST_NAME("ADD Gd, FS:Ed");
SETFLAGS(X_ALL, SF_SET);
@@ -204,6 +205,17 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
}
break;
case 0xA0:
INST_NAME("MOV AL, FS:Id");
grab_fsdata(dyn, addr, ninst, x1);
i32 = F32S;
if(i32>-4096 && i32<4096) {
LDRB_IMM9(xEAX, x1, i32);
} else {
MOV32(x2, i32);
LDRB_REG_LSL_IMM5(xEAX, x1, x2, 0);
}
break;
case 0xA1:
INST_NAME("MOV EAX, FS:Id");
grab_fsdata(dyn, addr, ninst, x1);
@@ -215,7 +227,17 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
LDR_REG_LSL_IMM5(xEAX, x1, x2, 0);
}
break;
case 0xA2:
INST_NAME("MOV FS:Od, AL");
grab_fsdata(dyn, addr, ninst, x1);
i32 = F32S;
if(i32>-4096 && i32<4096) {
STRB_IMM9(xEAX, x1, i32);
} else {
MOV32(x2, i32);
STRB_REG_LSL_IMM5(xEAX, x1, x2, 0);
}
break;
case 0xA3:
INST_NAME("MOV FS:Od, EAX");
grab_fsdata(dyn, addr, ninst, x1);
@@ -254,6 +276,32 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
nextop = F8;
grab_fsdata(dyn, addr, ninst, x12);
switch((nextop>>3)&7) {
case 2: // CALL Ed
INST_NAME("CALL Ed");
PASS2IF(ninst && dyn->insts && dyn->insts[ninst-1].x86.set_flags, 1) {
READFLAGS(X_PEND); // that's suspicious
} else {
SETFLAGS(X_ALL, SF_SET); //Hack to put flag in "don't care" state
}
if((nextop&0xC0)==0xC0) { // reg
MOV_REG(xEIP, xEAX+(nextop&7));
} else { // mem
addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
LDR_REG_LSL_IMM5(xEIP, ed, x12, 0);
}
BARRIER(1);
BARRIER_NEXT(1);
if(!dyn->nolinker && (!dyn->insts || ninst!=dyn->size-1)) {
PASS2(cstack_push(dyn, ninst, addr, dyn->insts[ninst+1].address, x1, x2);)
} else {
PASS2(cstack_push(dyn, ninst, 0, 0, x1, x2);)
*need_epilog = 0;
*ok = 0;
MOV32(x2, addr);
}
PUSH(xESP, 1<<x2);
jump_to_linker(dyn, 0, xEIP, ninst); // smart linker
break;
case 6: // Push Ed
INST_NAME("PUSH FS:Ed");
if((nextop&0xC0)==0xC0) { // reg
+90 -1
View File
@@ -28,12 +28,16 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
int32_t i32, j32;
uint32_t u32;
uint8_t gd, ed;
uint8_t wback;
uint8_t wback, wb1, wb2;
uint8_t u8;
int fixedaddress;
MAYUSE(j32);
MAYUSE(wback);
MAYUSE(wb2);
switch(opcode) {
case 0x03:
INST_NAME("ADD Gd, GS:Ed");
SETFLAGS(X_ALL, SF_SET);
@@ -74,6 +78,91 @@ uintptr_t dynarecGS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
emit_cmp32(dyn, ninst, gd, ed, x3, x12);
break;
case 0x80:
case 0x82:
nextop = F8;
switch((nextop>>3)&7) {
case 0: //ADD
INST_NAME("ADD GS:Eb, Ib");
SETFLAGS(X_ALL, SF_SET);
grab_tlsdata(dyn, addr, ninst, x1);
GETEBO(x1);
u8 = F8;
emit_add8c(dyn, ninst, x1, u8, x2, x12);
EBBACK;
break;
case 1: //OR
INST_NAME("OR GS:Eb, Ib");
SETFLAGS(X_ALL, SF_SET);
grab_tlsdata(dyn, addr, ninst, x1);
GETEBO(x1);
u8 = F8;
emit_or8c(dyn, ninst, x1, u8, x2, x12);
EBBACK;
break;
case 2: //ADC
INST_NAME("ADC GS:Eb, Ib");
READFLAGS(X_CF);
SETFLAGS(X_ALL, SF_SET);
grab_tlsdata(dyn, addr, ninst, x1);
GETEBO(x1);
u8 = F8;
emit_adc8c(dyn, ninst, x1, u8, x2, x12);
EBBACK;
break;
case 3: //SBB
INST_NAME("SBB GS:Eb, Ib");
READFLAGS(X_CF);
SETFLAGS(X_ALL, SF_SET);
grab_tlsdata(dyn, addr, ninst, x1);
GETEBO(x1);
u8 = F8;
emit_sbb8c(dyn, ninst, x1, u8, x2, x12);
EBBACK;
break;
case 4: //AND
INST_NAME("AND GS:Eb, Ib");
SETFLAGS(X_ALL, SF_SET);
grab_tlsdata(dyn, addr, ninst, x1);
GETEBO(x1);
u8 = F8;
emit_and8c(dyn, ninst, x1, u8, x2, x12);
EBBACK;
break;
case 5: //SUB
INST_NAME("SUB GS:Eb, Ib");
SETFLAGS(X_ALL, SF_SET);
grab_tlsdata(dyn, addr, ninst, x1);
GETEBO(x1);
u8 = F8;
emit_sub8c(dyn, ninst, x1, u8, x2, x12);
EBBACK;
break;
case 6: //XOR
INST_NAME("XOR GS:Eb, Ib");
SETFLAGS(X_ALL, SF_SET);
grab_tlsdata(dyn, addr, ninst, x1);
GETEBO(x1);
u8 = F8;
emit_xor8c(dyn, ninst, x1, u8, x2, x12);
EBBACK;
break;
case 7: //CMP
INST_NAME("CMP GS:Eb, Ib");
SETFLAGS(X_ALL, SF_SET);
grab_tlsdata(dyn, addr, ninst, x1);
GETEBO(x1);
u8 = F8;
if(u8) {
MOVW(x2, u8);
emit_cmp8(dyn, ninst, x1, x2, x3, x12);
} else {
emit_cmp8_0(dyn, ninst, x1, x3, x12);
}
break;
}
break;
case 0x89:
INST_NAME("MOV GS:Ed, Gd");
grab_tlsdata(dyn, addr, ninst, x12);
+36 -10
View File
@@ -83,7 +83,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
STRH_IMM8(x2, x1, 0);
ADD_IMM8(xESP, xESP, 2);
MOVW(x1, 0);
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_clean[_ES]));
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_serial[_ES]));
break;
case 0x09:
@@ -325,8 +325,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
case 0x56:
case 0x57:
INST_NAME("PUSH Reg16");
SUB_IMM8(xESP, xESP, 2);
STRH_IMM8(xEAX+(opcode&7), xESP, 0); //TODO: use a single STRH pre-decrement instruction
PUSH16(xEAX+(opcode&7), xESP);
break;
case 0x58:
case 0x59:
@@ -337,17 +336,45 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
case 0x5E:
case 0x5F:
INST_NAME("POP Reg16");
LDRH_IMM8(x1, xESP, 0); //TODO: use a single LDRH post-increment instruction
POP16(x1, xESP);
BFI(xEAX+(opcode&7), x1, 0, 16);
ADD_IMM8(xESP, xESP, 2);
break;
case 0x60:
INST_NAME("PUSHA");
MOV_REG(x1, xESP);
PUSH16(xEAX, xESP);
PUSH16(xECX, xESP);
PUSH16(xEDX, xESP);
PUSH16(xEBX, xESP);
PUSH16(x1, xESP);
PUSH16(xEBP, xESP);
PUSH16(xESI, xESP);
PUSH16(xEDI, xESP);
break;
case 0x61:
INST_NAME("POPA");
POP16(x1, xESP);
BFI(xEDI, x1, 0, 16);
POP16(x1, xESP);
BFI(xESI, x1, 0, 16);
POP16(x1, xESP);
BFI(xEBP, x1, 0, 16);
ADD_IMM8(xESP, xESP, 2); //POP16(xESP, xESP);
POP16(x1, xESP);
BFI(xEBX, x1, 0, 16);
POP16(x1, xESP);
BFI(xEDX, x1, 0, 16);
POP16(x1, xESP);
BFI(xECX, x1, 0, 16);
POP16(x1, xESP);
BFI(xEAX, x1, 0, 16);
break;
case 0x68:
INST_NAME("PUSH Iw");
u16 = F16;
MOVW(x2, u16);
SUB_IMM8(xESP, xESP, 2);
STRH_IMM8(x2, xESP, 0);
PUSH16(x2, xESP);
break;
case 0x69:
INST_NAME("IMUL Gw,Ew,Iw");
@@ -365,8 +392,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
INST_NAME("PUSH Ib");
i16 = F8S;
MOVW(x2, i16);
SUB_IMM8(xESP, xESP, 2);
STRH_IMM8(x2, xESP, 0);
PUSH16(x2, xESP);
break;
case 0x6B:
INST_NAME("IMUL Gw,Ew,Ib");
@@ -527,7 +553,7 @@ uintptr_t dynarec66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
STRH_REG(x1, xEmu, x2);
}
MOVW(x1, 0);
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_clean[(nextop&0x38)>>3]));
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_serial[(nextop&0x38)>>3]));
break;
case 0x90:
+104 -6
View File
@@ -172,7 +172,7 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-8, 0);
LDR_IMM9(x2, ed, fixedaddress);
LDR_IMM9(x3, ed, fixedaddress+4);
VMOVfrV_D(x2, x3, v0+1);
VMOVtoV_D(v0+1,x2, x3);
}
break;
case 0x17:
@@ -334,6 +334,52 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
VSUBQ_16(q0, q0, v1);
break;
case 0x08:
INST_NAME("PSIGNB Gx, Ex");
nextop = F8;
GETGX(q0);
GETEX(q1);
v1 = fpu_get_scratch_quad(dyn);
v0 = fpu_get_scratch_quad(dyn);
VNEGNQ_8(v0, q0); // get NEG
VCLTQ_0_8(v1, q1); // calculate mask
VBICQ(q0, q0, v1); // apply not mask on dest
VANDQ(v0, v0, v1); // apply mask on src
VORRQ(q0, q0, v0); // merge
VCEQQ_0_8(v1, q1); // handle case where Ex is 0
VBICQ(q0, q0, v1);
break;
case 0x09:
INST_NAME("PSIGNW Gx, Ex");
nextop = F8;
GETGX(q0);
GETEX(q1);
v1 = fpu_get_scratch_quad(dyn);
v0 = fpu_get_scratch_quad(dyn);
VNEGNQ_16(v0, q0); // get NEG
VCLTQ_0_16(v1, q1); // calculate mask
VBICQ(q0, q0, v1); // apply not mask on dest
VANDQ(v0, v0, v1); // apply mask on src
VORRQ(q0, q0, v0); // merge
VCEQQ_0_16(v1, q1); // handle case where Ex is 0
VBICQ(q0, q0, v1);
break;
case 0x0A:
INST_NAME("PSIGND Gx, Ex");
nextop = F8;
GETGX(q0);
GETEX(q1);
v1 = fpu_get_scratch_quad(dyn);
v0 = fpu_get_scratch_quad(dyn);
VNEGNQ_32(v0, q0); // get NEG
VCLTQ_0_32(v1, q1); // calculate mask
VBICQ(q0, q0, v1); // apply not mask on dest
VANDQ(v0, v0, v1); // apply mask on src
VORRQ(q0, q0, v0); // merge
VCEQQ_0_32(v1, q1); // handle case where Ex is 0
VBICQ(q0, q0, v1);
break;
case 0x0B:
INST_NAME("PMULHRSW Gx,Ex");
nextop = F8;
@@ -341,6 +387,31 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
GETEX(q1);
VQRDMULHQ_S16(q0, q0, q1);
break;
case 0x1C:
INST_NAME("PABSB Gx,Ex");
nextop = F8;
GETEX(q1);
gd = (nextop&0x38)>>3;
q0 = sse_get_reg_empty(dyn, ninst, x1, gd);
VABSQ_S8(q0, q1);
break;
case 0x1D:
INST_NAME("PABSW Gx,Ex");
nextop = F8;
GETEX(q1);
gd = (nextop&0x38)>>3;
q0 = sse_get_reg_empty(dyn, ninst, x1, gd);
VABSQ_S16(q0, q1);
break;
case 0x1E:
INST_NAME("PABSD Gx,Ex");
nextop = F8;
GETEX(q1);
gd = (nextop&0x38)>>3;
q0 = sse_get_reg_empty(dyn, ninst, x1, gd);
VABSQ_S32(q0, q1);
break;
default:
DEFAULT;
}
@@ -1377,10 +1448,15 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
if(v0==v1 && u8==0) {
VMOVD(v0+1, v0);
} else {
q0 = fpu_get_scratch_quad(dyn);
if(v0==v1)
q0 = fpu_get_scratch_quad(dyn);
else
q0 = v0;
VMOVD(q0, v0+(u8&1));
VMOVD(q0+1, v1+((u8>>1)&1));
VMOVQ(v0, q0);
if(v0==v1) {
VMOVQ(v0, q0);
}
}
break;
@@ -1593,7 +1669,17 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
GETEX(q0);
VRHADDQ_U16(v0, v0, q0);
break;
case 0xE4:
INST_NAME("PMULHUW Gx,Ex");
nextop = F8;
GETGX(v0);
GETEX(v1);
q0 = fpu_get_scratch_quad(dyn);
VMULL_U32_U16(q0, v0, v1);
VSHRN_32(v0, q0, 16);
VMULL_U32_U16(q0, v0+1, v1+1);
VSHRN_32(v0+1, q0, 16);
break;
case 0xE5:
INST_NAME("PMULHW Gx,Ex");
nextop = F8;
@@ -1648,7 +1734,13 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
GETEX(q0);
VQSUBQ_S16(v0, v0, q0);
break;
case 0xEA:
INST_NAME("PMINSW Gx,Ex");
nextop = F8;
GETGX(v0);
GETEX(q0);
VMINQ_S16(v0, v0, q0);
break;
case 0xEB:
INST_NAME("POR Gx,Ex");
nextop = F8;
@@ -1670,7 +1762,13 @@ uintptr_t dynarec660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
GETEX(q0);
VQADDQ_S16(v0, v0, q0);
break;
case 0xEE:
INST_NAME("PMAXSW Gx,Ex");
nextop = F8;
GETGX(v0);
GETEX(q0);
VMAXQ_S16(v0, v0, q0);
break;
case 0xEF:
INST_NAME("PXOR Gx,Ex");
nextop = F8;
+6 -4
View File
@@ -28,7 +28,6 @@ uintptr_t dynarec67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
int32_t i32, j32;
uint32_t u32;
uint8_t gd, ed;
uint8_t wback;
int fixedaddress;
MAYUSE(i32);
@@ -65,10 +64,13 @@ uintptr_t dynarec67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
grab_fsdata(dyn, addr, ninst, x12);
GETGD;
if((nextop&0xC0)==0xC0) { // reg <= reg
MOV_REG(gd, xEAX+(nextop&7));
ed = xEAX+(nextop&7);
if(ed!=gd) {
BFI(gd, ed, 0, 16);
}
} else { // mem <= reg
addr = geted16(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0, 0);
LDR_REG_LSL_IMM5(gd, ed, x12, 0);
LDR_REG_LSL_IMM5(gd, x12, ed, 0);
}
break;
@@ -81,7 +83,7 @@ uintptr_t dynarec67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
} else {
addr = geted16(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0);
POP(xESP, (1<<x2));
STR_REG_LSL_IMM5(x2, x1, x12, 0);
STR_REG_LSL_IMM5(x2, x12, ed, 0);
}
break;
+34 -27
View File
@@ -151,22 +151,23 @@ uintptr_t dynarecDF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
case 1:
INST_NAME("FISTTP Ew, ST0");
v1 = x87_get_st(dyn, ninst, x1, x2, 0);
u8 = x87_setround(dyn, ninst, x1, x2, x12);
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 255, 0);
ed = x1;
s0 = fpu_get_scratch_single(dyn);
VCVT_S32_F64(s0, v1);
MSR_nzcvq_0();
// x1 already have FPCSR reg to clear exceptions flags
ORR_IMM8(x3, x1, 0b001, 6); // enable exceptions
BIC_IMM8(x3, x3, 0b10011111, 0);
VMSR(x3);
VCVTR_S32_F64(s0, v1);
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
VMOVfrV(ed, s0);
MSR_nzcvq_0(); // reset Q flag (and all other flags too)
SSAT_REG_LSL_IMM5(ed, 16, ed, 0);
MRS_aspr(x3); // check Q flag
TSTS_IMM8_ROR(x3, 0b10, 3);
B_MARK(cEQ); // not saturated, continue
MOV32(ed, 0xffff8000);
MARK;
STRH_IMM8(ed, wback, fixedaddress);
TSTS_IMM8_ROR(x3, 0b00000001, 0);
SSAT_REG_LSL_IMM5_COND(cEQ, x3, 16, ed, 0);
CMPS_REG_LSL_IMM5_COND(cEQ, ed, x3, 0);
MOVW_COND(cNE, x3, 0x8000); // saturated
STRH_IMM8(x3, wback, fixedaddress);
x87_do_pop(dyn, ninst);
x87_restoreround(dyn, ninst, u8);
break;
case 2:
INST_NAME("FIST Ew, ST0");
@@ -175,16 +176,19 @@ uintptr_t dynarecDF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 255, 0);
ed = x1;
s0 = fpu_get_scratch_single(dyn);
MSR_nzcvq_0();
// x1 already have FPCSR reg to clear exceptions flags
ORR_IMM8(x3, x1, 0b001, 6); // enable exceptions
BIC_IMM8(x3, x3, 0b10011111, 0);
VMSR(x3);
VCVTR_S32_F64(s0, v1);
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
VMOVfrV(ed, s0);
MSR_nzcvq_0(); // reset Q flag (and all other flags too)
SSAT_REG_LSL_IMM5(ed, 16, ed, 0);
MRS_aspr(x3); // check Q flag
TSTS_IMM8_ROR(x3, 0b10, 3);
B_MARK(cEQ); // not saturated, continue
MOV32(ed, 0xffff8000);
MARK;
STRH_IMM8(ed, wback, fixedaddress);
TSTS_IMM8_ROR(x3, 0b00000001, 0);
SSAT_REG_LSL_IMM5_COND(cEQ, x3, 16, ed, 0);
CMPS_REG_LSL_IMM5_COND(cEQ, ed, x3, 0);
MOVW_COND(cNE, x3, 0x8000); // saturated
STRH_IMM8(x3, wback, fixedaddress);
x87_restoreround(dyn, ninst, u8);
break;
case 3:
@@ -194,16 +198,19 @@ uintptr_t dynarecDF(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 255, 0);
ed = x1;
s0 = fpu_get_scratch_single(dyn);
MSR_nzcvq_0();
// x1 already have FPCSR reg to clear exceptions flags
ORR_IMM8(x3, x1, 0b001, 6); // enable exceptions
BIC_IMM8(x3, x3, 0b10011111, 0);
VMSR(x3);
VCVTR_S32_F64(s0, v1);
VMRS(x3); // get the FPCSR reg and test FPU execption (invalid operation only)
VMOVfrV(ed, s0);
MSR_nzcvq_0(); // reset Q flag (and all other flags too)
SSAT_REG_LSL_IMM5(ed, 16, ed, 0);
MRS_aspr(x3); // check Q flag
TSTS_IMM8_ROR(x3, 0b10, 3);
B_MARK(cEQ); // not saturated, continue
MOV32(ed, 0xffff8000);
MARK;
STRH_IMM8(ed, wback, fixedaddress);
TSTS_IMM8_ROR(x3, 0b00000001, 0);
SSAT_REG_LSL_IMM5_COND(cEQ, x3, 16, ed, 0);
CMPS_REG_LSL_IMM5_COND(cEQ, ed, x3, 0);
MOVW_COND(cNE, x3, 0x8000); // saturated
STRH_IMM8(x3, wback, fixedaddress);
x87_do_pop(dyn, ninst);
x87_restoreround(dyn, ninst, u8);
break;
+11 -1
View File
@@ -511,7 +511,17 @@ uintptr_t dynarecF0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
case 0x87:
--addr;
break;
case 0x90: // This is xchg reg, reg, so let's ignore the LOCK prefix...
case 0x91:
case 0x92:
case 0x93:
case 0x94:
case 0x95:
case 0x96:
case 0x97:
--addr;
break;
case 0x0F:
nextop = F8;
switch(nextop) {
+1 -1
View File
@@ -58,7 +58,7 @@ uintptr_t dynarecF20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
MAYUSE(d0);
switch(nextop) {
case 0x10:
INST_NAME("MOVSD Gx, Ex");
nextop = F8;
+53 -6
View File
@@ -63,9 +63,10 @@ uintptr_t dynarecF30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
int v0, v1;
int s0, s1, s2;
int d0, d1;
int q0;
int q0, q1;
int parity;
MAYUSE(q1);
MAYUSE(s1);
MAYUSE(s2);
MAYUSE(j32);
@@ -132,6 +133,38 @@ uintptr_t dynarecF30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
STR_IMM9(x2, ed, fixedaddress);
}
break;
case 0x12:
INST_NAME("MOVSLDUP Gx, Ex");
nextop = F8;
gd = (nextop&0x38)>>3;
if((nextop&0xC0)==0xC0) {
q1 = sse_get_reg(dyn, ninst, x1, nextop&7);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0);
q1 = fpu_get_scratch_quad(dyn);
VLD1Q_64(q1, ed);
}
q0 = sse_get_reg_empty(dyn, ninst, x1, gd);
VDUP_32(q0+0, q1+0, 0);
VDUP_32(q0+1, q1+1, 0);
break;
case 0x16:
INST_NAME("MOVSHDUP Gx, Ex");
nextop = F8;
gd = (nextop&0x38)>>3;
if((nextop&0xC0)==0xC0) {
q1 = sse_get_reg(dyn, ninst, x1, nextop&7);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0, 0);
q1 = fpu_get_scratch_quad(dyn);
VLD1Q_64(q1, ed);
}
q0 = sse_get_reg_empty(dyn, ninst, x1, gd);
VDUP_32(q0+0, q1+0, 1);
VDUP_32(q0+1, q1+1, 1);
break;
case 0x1E:
INST_NAME("NOP / ENDBR32 / ENDBR64");
@@ -179,8 +212,15 @@ uintptr_t dynarecF30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
}
VMOV_32(s0, d0*2);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3);
VLDR_32(s0, ed, fixedaddress);
parity = getedparity(dyn, ninst, addr, nextop, 3);
if(parity) {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3);
VLDR_32(s0, ed, fixedaddress);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095, 0);
LDR_IMM9(x2, ed, fixedaddress);
VMOVtoV(s0, x2);
}
}
VCVT_S32_F32(s0, s0);
VMOVfrV(gd, s0);
@@ -201,8 +241,15 @@ uintptr_t dynarecF30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
}
VMOV_32(s0, d0*2);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3);
VLDR_32(s0, ed, fixedaddress);
parity = getedparity(dyn, ninst, addr, nextop, 3);
if(parity) {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 1023, 3);
VLDR_32(s0, ed, fixedaddress);
} else {
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095, 0);
LDR_IMM9(x2, ed, fixedaddress);
VMOVtoV(s0, x2);
}
}
VCVTR_S32_F32(s0, s0);
VMOVfrV(gd, s0);
@@ -588,7 +635,7 @@ uintptr_t dynarecF30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nins
addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 4095-8, 0);
LDR_IMM9(x2, ed, fixedaddress);
LDR_IMM9(x3, ed, fixedaddress+4);
VMOVfrV_D(x2, x3, v0);
VMOVtoV_D(v0, x2, x3);
}
}
gd = (nextop&0x38)>>3;
+32 -4
View File
@@ -117,8 +117,10 @@ void arm_fbld(x86emu_t* emu, uint8_t* ed)
void arm_fild64(x86emu_t* emu, int64_t* ed)
{
ST0.d = *ed;
STll(0).ll = *ed;
int64_t tmp;
memcpy(&tmp, ed, sizeof(tmp));
ST0.d = tmp;
STll(0).ll = tmp;
STll(0).ref = ST0.ll;
}
@@ -134,10 +136,10 @@ void arm_fistp64(x86emu_t* emu, int64_t* ed)
memcpy(ed, &STll(0).ll, sizeof(int64_t));
} else {
int64_t tmp;
if(isgreater(ST0.d, (double)(int64_t)0x7fffffffffffffffLL) || isless(ST0.d, (double)(int64_t)0x8000000000000000LL))
if(isgreater(ST0.d, (double)(int64_t)0x7fffffffffffffffLL) || isless(ST0.d, (double)(int64_t)0x8000000000000000LL) || !isfinite(ST0.d))
tmp = 0x8000000000000000LL;
else
tmp = (int64_t)ST0.d;
tmp = fpu_round(emu, ST0.d);
memcpy(ed, &tmp, sizeof(tmp));
}
}
@@ -304,3 +306,29 @@ int getedparity(dynarec_arm_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, i
#undef F8
#undef F32
}
int isNativeCall(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t* calladdress, int* retn)
{
#define PK(a) *(uint8_t*)(addr+a)
#define PK32(a) *(uint32_t*)(addr+a)
if(!addr)
return 0;
if(PK(0)==0xff && PK(1)==0x25) { // absolute jump, maybe the GOT
uintptr_t a1 = (PK32(2)); // need to add a check to see if the address is from the GOT !
addr = *(uint32_t*)a1;
}
if(addr<0x10000) // too low, that is suspicious
return 0;
onebridge_t *b = (onebridge_t*)(addr);
if(b->CC==0xCC && b->S=='S' && b->C=='C' && b->w!=(wrapper_t)0 && b->f!=(uintptr_t)PltResolver) {
// found !
if(retn) *retn = (b->C3==0xC2)?b->N:0;
if(calladdress) *calladdress = addr+1;
return 1;
}
return 0;
#undef PK32
#undef PK
}
+3
View File
@@ -54,4 +54,7 @@ void fpu_reset_reg(dynarec_arm_t* dyn);
// Get if ED will have the correct parity. Not emiting anything. Parity is 2 for DWORD or 3 for QWORD
int getedparity(dynarec_arm_t* dyn, int ninst, uintptr_t addr, uint8_t nextop, int parity);
// Is what pointed at addr a native call? And if yes, to what function?
int isNativeCall(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t* calladdress, int* retn);
#endif //__DYNAREC_ARM_FUNCTIONS_H__
+26 -31
View File
@@ -17,6 +17,7 @@
#include "x86trace.h"
#include "dynarec_arm.h"
#include "dynarec_arm_private.h"
#include "dynablock_private.h"
#include "arm_printer.h"
#include "../tools/bridge_private.h"
@@ -292,6 +293,8 @@ void jump_to_linker(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
MOV32_(x1, (uintptr_t)table);
// TODO: This is not thread safe.
if(!ip) { // no IP, jump address in a reg, so need smart linker
#if 0
//version thread safe
MARK;
LDREXD(x2, x1); // load dest address in x2 and planned ip in x3
CMPS_REG_LSL_IMM5(xEIP, x3, 0);
@@ -304,6 +307,16 @@ void jump_to_linker(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst)
MOV_REG(x12, x3); // put back IP in place...
B_MARK(cEQ);
BX(x2); // go to linker
#else
// not thread safe, is that still ok?
LDRD_IMM8(x2, x1, 0);
CMPS_REG_LSL_IMM5(xEIP, x3, 0);
BXcond(cEQ, x2);
MOV32_(x2, (uintptr_t)arm_linker);
MOV_REG(x3, x12);
STRD_IMM8(x2, x1, 0);
BX(x2);
#endif
} else {
LDR_IMM9(x2, x1, 0);
BX(x2); // jump
@@ -411,7 +424,7 @@ void iret_to_epilog(dynarec_arm_t* dyn, int ninst)
POP(xESP, 1<<x2);
STRH_REG(x2, xEmu, x1);
MOVW(x1, 0);
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_clean[_CS]));
STR_IMM9(x1, xEmu, offsetof(x86emu_t, segs_serial[_CS]));
// POP EFLAGS
POP(xESP, (1<<x1));
CALL(arm_popf, -1, (1<<xEIP));
@@ -444,12 +457,14 @@ void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, uint32_t
void grab_tlsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg)
{
MESSAGE(LOG_DUMP, "Get TLSData\n");
//int32_t i32;
//MAYUSE(i32);
//LDR_IMM9(x12, xEmu, offsetof(x86emu_t, segs_clean[_GS]));
//CMPS_IMM8(x12, 1);
//LDR_IMM9_COND(cEQ, reg, xEmu, offsetof(x86emu_t, segs_offs[_GS]));
//B_MARKSEG(cEQ);
int32_t j32;
MAYUSE(j32);
LDR_IMM9(x1, xEmu, offsetof(x86emu_t, context));
LDR_IMM9(x12, xEmu, offsetof(x86emu_t, segs_serial[_GS])); // complete check here
LDR_IMM9(x1, x1, offsetof(box86context_t, sel_serial));
CMPS_REG_LSL_IMM5(x12, x1, 0);
LDR_IMM9_COND(cEQ, reg, xEmu, offsetof(x86emu_t, segs_offs[_GS]));
B_MARKSEG(cEQ);
MOVW(x1, _GS);
call_c(dyn, ninst, GetSegmentBaseEmu, 12, reg, 0);
MARKSEG;
@@ -461,36 +476,16 @@ void grab_fsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg)
int32_t j32;
MAYUSE(j32);
MESSAGE(LOG_DUMP, "Get FS: Offset\n");
LDR_IMM9(x12, xEmu, offsetof(x86emu_t, segs_clean[_FS]));
CMPS_IMM8(x12, 1);
LDR_IMM9_COND(cEQ, reg, xEmu, offsetof(x86emu_t, segs_offs[_FS]));
B_MARKSEG(cEQ);
LDR_IMM9(x12, xEmu, offsetof(x86emu_t, segs_serial[_FS]));// fast check here
CMPS_IMM8(x12, 0);
LDR_IMM9_COND(cNE, reg, xEmu, offsetof(x86emu_t, segs_offs[_FS]));
B_MARKSEG(cNE);
MOVW(x1, _FS);
call_c(dyn, ninst, GetSegmentBaseEmu, 12, reg, 0);
MARKSEG;
MESSAGE(LOG_DUMP, "----FS: Offset\n");
}
int isNativeCall(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t* calladdress, int* retn)
{
if(!addr)
return 0;
if(PK(0)==0xff && PK(1)==0x25) { // absolute jump, maybe the GOT
uintptr_t a1 = (PK32(2)); // need to add a check to see if the address is from the GOT !
addr = *(uint32_t*)a1;
}
if(addr<0x10000) // too low, that is suspicious
return 0;
onebridge_t *b = (onebridge_t*)(addr);
if(b->CC==0xCC && b->S=='S' && b->C=='C' && b->w!=(wrapper_t)0) {
// found !
if(retn) *retn = (b->C3==0xC2)?b->N:0;
if(calladdress) *calladdress = addr+1;
return 1;
}
return 0;
}
// x87 stuffs
static void x87_reset(dynarec_arm_t* dyn, int ninst)
{
+24 -3
View File
@@ -132,6 +132,21 @@
wb1 = 1; \
ed = i; \
}
//GETEBO will use i for ed, i is also Offset, and can use r3 for wback.
#define GETEBO(i) if((nextop&0xC0)==0xC0) { \
wback = (nextop&7); \
wb2 = (wback>>2); \
wback = xEAX+(wback&3); \
UXTB(i, wback, wb2); \
wb1 = 0; \
ed = i; \
} else { \
addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, 0, 0); \
ADD_REG_LSL_IMM5(wback, wback, i, 0); \
LDRB_IMM9(i, wback, fixedaddress); \
wb1 = 1; \
ed = i; \
}
//GETSEB sign extend EB, will use i for ed, and can use r3 for wback.
#define GETSEB(i) if((nextop&0xC0)==0xC0) { \
wback = (nextop&7); \
@@ -268,7 +283,7 @@
#ifndef READFLAGS
#define READFLAGS(A) \
if(dyn->state_flags!=SF_SET) { \
if(((A)!=X_PEND) && dyn->state_flags!=SF_SET) { \
if(dyn->state_flags!=SF_PENDING) { \
LDR_IMM9(x3, xEmu, offsetof(x86emu_t, df)); \
TSTS_REG_LSL_IMM5(x3, x3, 0); \
@@ -308,6 +323,14 @@
#define NEW_BARRIER_INST
#endif
#if STEP < 2
#define PASS2IF(A, B) if(A)
#elif STEP == 2
#define PASS2IF(A, B) if(A) dyn->insts[ninst].pass2choice = B; if(dyn->insts[ninst].pass2choice == B)
#else
#define PASS2IF(A, B) if(dyn->insts[ninst].pass2choice == B)
#endif
void arm_epilog();
void* arm_linker(x86emu_t* emu, void** table, uintptr_t addr);
@@ -349,7 +372,6 @@ void* arm_linker(x86emu_t* emu, void** table, uintptr_t addr);
#define call_c STEPNAME(call_c_)
#define grab_fsdata STEPNAME(grab_fsdata_)
#define grab_tlsdata STEPNAME(grab_tlsdata_)
#define isNativeCall STEPNAME(isNativeCall_)
#define emit_cmp8 STEPNAME(emit_cmp8)
#define emit_cmp16 STEPNAME(emit_cmp16)
#define emit_cmp32 STEPNAME(emit_cmp32)
@@ -467,7 +489,6 @@ void iret_to_epilog(dynarec_arm_t* dyn, int ninst);
void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, uint32_t mask);
void grab_fsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg);
void grab_tlsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg);
int isNativeCall(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t* calladdress, int* retn);
void emit_lock(dynarec_arm_t* dyn, uintptr_t addr, int ninst);
void emit_unlock(dynarec_arm_t* dyn, uintptr_t addr, int ninst);
void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4);
+1 -1
View File
@@ -8,7 +8,7 @@
#define SETFLAGS(A,B) {dyn->insts[ninst].x86.set_flags = A; dyn->insts[ninst].x86.state_flags = B;}
#define JUMP(A) dyn->insts[ninst].x86.jmp = A
#define BARRIER(A) dyn->insts[ninst].x86.barrier = A
#define BARRIER_NEXT(A) if(ninst+1<dyn->size) dyn->insts[ninst+1].x86.barrier = A
#define BARRIER_NEXT(A) if(ninst<dyn->size) dyn->insts[ninst+1].x86.barrier = A
#define NEW_INST \
dyn->insts[ninst].x86.addr = ip; \
+3 -2
View File
@@ -2,8 +2,9 @@
#define FINI
#define EMIT(A) \
if(box86_dynarec_dump) {dynarec_log(LOG_NONE, "\t%08x\t%s\n", (A), arm_print(A));} \
*(uint32_t*)(dyn->block) = A; \
dyn->block += 4; dyn->arm_size += 4
*(uint32_t*)(dyn->block) = A; \
dyn->block += 4; dyn->arm_size += 4;\
dyn->insts[ninst].size2 += 4
#define MESSAGE(A, ...) if(box86_dynarec_dump) dynarec_log(LOG_NONE, __VA_ARGS__)
#define NEW_INST
+4
View File
@@ -10,10 +10,14 @@ typedef struct instruction_arm_s {
uintptr_t address; // (start) address of the arm emited instruction
uintptr_t epilog; // epilog of current instruction (can be start of next, of barrier stuff)
int size; // size of the arm emited instruction
int size2; // size of the arm emited instrucion after pass2
uintptr_t mark, mark2, mark3;
uintptr_t markf;
uintptr_t markseg;
uintptr_t marklock;
int pass2choice;// value for choices that are fixed on pass2 for pass3
uintptr_t natcall;
int retn;
} instruction_arm_t;
typedef struct dynarec_arm_s {
+6
View File
@@ -40,6 +40,7 @@ const char* DumpSection(Elf32_Shdr *s, char* SST) {
GO(SHT_HIPROC);
GO(SHT_LOUSER);
GO(SHT_HIUSER);
#ifdef SHT_GNU_versym
GO(SHT_GNU_versym);
GO(SHT_GNU_ATTRIBUTES);
GO(SHT_GNU_HASH);
@@ -51,6 +52,7 @@ const char* DumpSection(Elf32_Shdr *s, char* SST) {
GO(SHT_SUNW_syminfo);
GO(SHT_GNU_verdef);
GO(SHT_GNU_verneed);
#endif
#undef GO
default:
sprintf(buff, "0x%X unknown type", s->sh_type);
@@ -98,6 +100,7 @@ const char* DumpDynamic(Elf32_Dyn *s) {
GO(DT_RUNPATH, 0);
GO(DT_FLAGS, 0);
GO(DT_ENCODING, 0);
#ifdef DT_NUM
GO(DT_NUM, 0);
GO(DT_VALRNGLO, 0);
GO(DT_GNU_PRELINKED, 0);
@@ -133,6 +136,7 @@ const char* DumpDynamic(Elf32_Dyn *s) {
GO(DT_VERNEEDNUM, 0);
GO(DT_AUXILIARY, 0);
GO(DT_FILTER, 0);
#endif
#undef GO
default:
sprintf(buff, "0x%X unknown type", s->d_tag);
@@ -154,11 +158,13 @@ const char* DumpPHEntry(Elf32_Phdr *e)
GO(PT_SHLIB);
GO(PT_PHDR);
GO(PT_TLS);
#ifdef PT_NUM
GO(PT_NUM);
GO(PT_LOOS);
GO(PT_GNU_EH_FRAME);
GO(PT_GNU_STACK);
GO(PT_GNU_RELRO);
#endif
#undef GO
default: sprintf(buff, "type: %x, Off=%x vaddr=%p paddr=%p filesz=%u memsz=%u flags=%x align=%u", e->p_type, e->p_offset, (void*)e->p_vaddr, (void*)e->p_paddr, e->p_filesz, e->p_memsz, e->p_flags, e->p_align); break;
}
+76 -33
View File
@@ -66,7 +66,7 @@ void FreeElfHeader(elfheader_t** head)
#ifdef DYNAREC
if(h->text) {
dynarec_log(LOG_INFO, "Free Dynarec block for %s\n", h->path);
cleanDBFromAddressRange(h->text, h->textsz, 1);
cleanDBFromAddressRange(my_context, h->text, h->textsz, 1);
}
#endif
free(h->name);
@@ -267,7 +267,7 @@ int LoadElfMemory(FILE* f, box86context_t* context, elfheader_t* head)
#ifdef DYNAREC
if(e->p_flags & PF_X) {
dynarec_log(LOG_DEBUG, "Add ELF eXecutable Memory %p:%p\n", dest, (void*)e->p_memsz);
addDBFromAddressRange((uintptr_t)dest, e->p_memsz, 0);
addDBFromAddressRange(context, (uintptr_t)dest, e->p_memsz, 0);
}
#endif
}
@@ -333,6 +333,7 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn
uint32_t *p = (uint32_t*)(rel[i].r_offset + head->delta);
uintptr_t offs = 0;
uintptr_t end = 0;
uintptr_t tmp = 0;
elfheader_t* h_tls = head;
if(bind==STB_LOCAL) {
offs = sym->st_value + head->delta;
@@ -459,7 +460,13 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, elfheader_t* head, int cn
}
break;
case R_386_JMP_SLOT:
if(bind==STB_LOCAL) {
// apply immediatly for gobject closure marshal or for LOCAL binding. Also, apply immediatly if it doesn't jump in the got
tmp = (uintptr_t)(*p);
if (bind==STB_LOCAL
|| ((symname && strstr(symname, "g_cclosure_marshal_")==symname))
|| !tmp
|| !((tmp>=head->plt && tmp<head->plt_end) || (tmp>=head->gotplt && tmp<head->gotplt_end))
) {
if (!offs) {
if(bind==STB_WEAK) {
printf_log(LOG_INFO, "Warning: Weak Symbol %s not found, cannot apply R_386_JMP_SLOT @%p (%p)\n", symname, p, *(void**)p);
@@ -574,7 +581,7 @@ int RelocateElfPlt(lib_t *maplib, lib_t *local_maplib, elfheader_t* head)
return -1;
}
if(pltResolver==~0) {
pltResolver = AddBridge(my_context->system, vFE, PltResolver, 0);
pltResolver = AddBridge(my_context->system, my_context, vFE, PltResolver, 0);
}
if(head->pltgot) {
*(uintptr_t*)(head->pltgot+head->delta+8) = pltResolver;
@@ -763,7 +770,7 @@ int LoadNeededLibs(elfheader_t* h, lib_t *maplib, needed_libs_t* neededlibs, int
printf_log(LOG_INFO, "BOX86: Warning, RPATH with $ variable not supported yet (%s)\n", rpath);
} else {
printf_log(LOG_DEBUG, "Prepending path \"%s\" to BOX86_LD_LIBRARY_PATH\n", rpath);
PrependPath(rpath, &box86->box86_ld_lib, 1);
PrependList(&box86->box86_ld_lib, rpath, 1);
}
if(rpath!=rpathref)
free(rpath);
@@ -786,12 +793,27 @@ int LoadNeededLibs(elfheader_t* h, lib_t *maplib, needed_libs_t* neededlibs, int
return 0;
}
int ElfCheckIfUseTCMallocMinimal(elfheader_t* h)
{
if(!h)
return 0;
for (int i=0; i<h->numDynamic; ++i)
if(h->Dynamic[i].d_tag==DT_NEEDED) {
char *needed = h->DynStrTab+h->delta+h->Dynamic[i].d_un.d_val;
if(!strcmp(needed, "libtcmalloc_minimal.so.4")) // tcmalloc needs to be the 1st lib loaded
return 1;
else
return 0;
}
return 0;
}
void RunElfInit(elfheader_t* h, x86emu_t *emu)
{
if(!h || h->init_done)
return;
// reset Segs Cache
memset(emu->segs_clean, 0, sizeof(emu->segs_clean));
memset(emu->segs_serial, 0, sizeof(emu->segs_serial));
uintptr_t p = h->initentry + h->delta;
box86context_t* context = GetEmuContext(emu);
if(context->deferedInit) {
@@ -979,17 +1001,21 @@ void* GetTLSPointer(box86context_t* context, elfheader_t* h)
#ifdef DYNAREC
dynablocklist_t* GetDynablocksFromAddress(box86context_t *context, uintptr_t addr)
{
// this is one is fast, so start with that
dynablocklist_t* ret = getDBFromAddress(addr);
// if we are here, the there is not block in standard "space"
/*dynablocklist_t* ret = getDBFromAddress(addr);
if(ret) {
return ret;
}*/
if(box86_dynarec_forced) {
addDBFromAddressRange(my_context, addr, 1, 1);
return my_context->dynmap[addr>>DYNAMAP_SHIFT];
}
//check if address is in an elf... if yes, grant a block (should I warn)
Dl_info info;
if(dladdr((void*)addr, &info)) {
dynarec_log(LOG_INFO, "Address %p is in a native Elf memory space (function \"%s\" in %s)\n", (void*)addr, info.dli_sname, info.dli_fname);
return NULL;
}
// nope
if(addr>0x100)
if((*(uint8_t*)addr)==0xCC || (((*(uint8_t*)addr)==0xC3 || (*(uint8_t*)addr)==0xC2) /*&& (*(uint8_t*)(addr-11))==0xCC*/) )
return context->dynablocks;
if(box86_dynarec_forced)
return context->dynablocks;
dynarec_log(LOG_INFO, "Address %p not found in Elf memory and is not a native call wrapper\n", (void*)addr);
return NULL;
}
@@ -1002,29 +1028,49 @@ typedef struct my_dl_phdr_info_s {
int dlpi_phnum;
} my_dl_phdr_info_t;
static int dl_iterate_phdr_callback(x86emu_t *emu, my_dl_phdr_info_t *info, size_t size, void* data)
static int dl_iterate_phdr_callback(x86emu_t *emu, void* F, my_dl_phdr_info_t *info, size_t size, void* data)
{
SetCallbackArgs(emu, 2, info, size);
int ret = RunCallback(emu);
int ret = RunFunctionWithEmu(emu, 0, (uintptr_t)F, 3, info, size, data);
return ret;
}
static int dl_iterate_phdr_native(struct dl_phdr_info* info, size_t size, void* data)
{
if(!info->dlpi_name)
return 0;
if(!info->dlpi_name[0]) // don't send informations about box86 itself
return 0;
#define SUPER() \
GO(0) \
GO(1) \
GO(2) \
GO(3) \
GO(4)
x86emu_t* emu = (x86emu_t*)data;
SetCallbackArgs(emu, 2, info, size);
int ret = RunCallback(emu);
return ret;
// dl_iterate_phdr ...
#define GO(A) \
static uintptr_t my_dl_iterate_phdr_fct_##A = 0; \
static int my_dl_iterate_phdr_##A(struct dl_phdr_info* a, size_t b, void* c)\
{ \
if(!a->dlpi_name) \
return 0; \
if(!a->dlpi_name[0]) /*don't send informations about box86 itself*/ \
return 0; \
return RunFunction(my_context, my_dl_iterate_phdr_fct_##A, 3, a, b, c); \
}
SUPER()
#undef GO
static void* find_dl_iterate_phdr_Fct(void* fct)
{
if(!fct) return fct;
if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
#define GO(A) if(my_dl_iterate_phdr_fct_##A == (uintptr_t)fct) return my_dl_iterate_phdr_##A;
SUPER()
#undef GO
#define GO(A) if(my_dl_iterate_phdr_fct_##A == 0) {my_dl_iterate_phdr_fct_##A = (uintptr_t)fct; return my_dl_iterate_phdr_##A; }
SUPER()
#undef GO
printf_log(LOG_NONE, "Warning, no more slot for elfloader dl_iterate_phdr callback\n");
return NULL;
}
#undef SUPER
EXPORT int my_dl_iterate_phdr(x86emu_t *emu, void* F, void *data) {
printf_log(LOG_INFO, "Warning: call to partially implemented dl_iterate_phdr(%p, %p)\n", F, data);
x86emu_t* cbemu = AddSharedCallback(emu, (uintptr_t)F, 3, NULL, NULL, data, NULL);
box86context_t *context = GetEmuContext(emu);
const char* empty = "";
int ret = 0;
@@ -1034,15 +1080,12 @@ EXPORT int my_dl_iterate_phdr(x86emu_t *emu, void* F, void *data) {
info.dlpi_name = idx?context->elfs[idx]->name:empty; //1st elf is program, and this one doesn't get a name
info.dlpi_phdr = context->elfs[idx]->PHEntries;
info.dlpi_phnum = context->elfs[idx]->numPHEntries;
if((ret = dl_iterate_phdr_callback(cbemu, &info, sizeof(info), data))) {
FreeCallback(cbemu);
if((ret = dl_iterate_phdr_callback(emu, F, &info, sizeof(info), data))) {
return ret;
}
}
// and now, go on native version
ret = dl_iterate_phdr(dl_iterate_phdr_native, cbemu);
// all done
FreeCallback(cbemu);
ret = dl_iterate_phdr(find_dl_iterate_phdr_Fct(F), data);
return ret;
}
+4
View File
@@ -52,8 +52,12 @@ struct elfheader_s {
int pltent;
uint32_t pltrel;
uintptr_t gotplt;
uintptr_t gotplt_end;
uintptr_t pltgot;
uintptr_t got;
uintptr_t got_end;
uintptr_t plt;
uintptr_t plt_end;
uintptr_t text;
int textsz;
+9 -1
View File
@@ -254,12 +254,20 @@ elfheader_t* ParseElfHeader(FILE* f, const char* name, int exec)
int ii = FindSection(h->SHEntries, h->numSHEntries, h->SHStrTab, ".got.plt");
if(ii) {
h->gotplt = h->SHEntries[ii].sh_addr;
h->gotplt_end = h->gotplt + h->SHEntries[ii].sh_size;
printf_log(LOG_DEBUG, "The GOT.PLT Table is at address %p\n", (void*)h->gotplt);
}
ii = FindSection(h->SHEntries, h->numSHEntries, h->SHStrTab, ".got");
if(ii) {
h->got = h->SHEntries[ii].sh_addr;
printf_log(LOG_DEBUG, "The GOT Table is at address %p\n", (void*)h->got);
h->got_end = h->got + h->SHEntries[ii].sh_size;
printf_log(LOG_DEBUG, "The GOT Table is at address %p..%p\n", (void*)h->got, (void*)h->got_end);
}
ii = FindSection(h->SHEntries, h->numSHEntries, h->SHStrTab, ".plt");
if(ii) {
h->plt = h->SHEntries[ii].sh_addr;
h->plt_end = h->plt + h->SHEntries[ii].sh_size;
printf_log(LOG_DEBUG, "The PLT Table is at address %p..%p\n", (void*)h->plt, (void*)h->plt_end);
}
// look for .init entry point
ii = FindSection(h->SHEntries, h->numSHEntries, h->SHStrTab, ".init");
+14 -4
View File
@@ -682,7 +682,7 @@
NEXT;
_0f_0xA1: /* POP FS */
emu->segs[_FS] = Pop(emu); // no check, no use....
emu->segs_clean[_FS] = 0;
emu->segs_serial[_FS] = 0;
NEXT;
_0f_0xA2: /* CPUID */
tmp32u = R_EAX;
@@ -716,7 +716,7 @@
NEXT;
_0f_0xA9: /* POP GS */
emu->segs[_GS] = Pop(emu);
emu->segs_clean[_GS] = 0;
emu->segs_serial[_GS] = 0;
NEXT;
@@ -1126,7 +1126,12 @@
GM.uw[i] = (tmp32s < 0) ? 0 : tmp32s;
}
NEXT;
_0f_0xDA: /* PMINUB Gm,Em */
nextop = F8;
GET_EM;
for (int i=0; i<8; ++i)
GM.ub[i] = (GM.ub[i]<EM->ub[i])?GM.ub[i]:EM->ub[i];
NEXT;
_0f_0xDB: /* PAND Gm,Em */
nextop = F8;
GET_EM;
@@ -1148,7 +1153,12 @@
GM.uw[i] = (tmp32u>65535) ? 65535 : tmp32u;
}
NEXT;
_0f_0xDE: /* PMAXUB Gm,Em */
nextop = F8;
GET_EM;
for (int i=0; i<8; ++i)
GM.ub[i] = (GM.ub[i]>EM->ub[i])?GM.ub[i]:EM->ub[i];
NEXT;
_0f_0xDF: /* PANDN Gm,Em */
nextop = F8;
GET_EM;
+13 -2
View File
@@ -30,7 +30,7 @@
NEXT;
_66_0x07: /* POP ES */
emu->segs[_ES] = Pop16(emu); // no check, no use....
emu->segs_clean[_ES] = 0;
emu->segs_serial[_ES] = 0;
NEXT;
_66_0x0F: /* 66 0f prefix */
@@ -39,6 +39,7 @@
Run660F(emu); // implemented in Run660f.c
ip = R_EIP;
if(emu->quit) goto fini;
STEP
NEXT;
_66_0x26: /* ES: */
@@ -215,7 +216,7 @@
nextop = F8;
GET_EW;
emu->segs[((nextop&0x38)>>3)] = EW->word[0];
emu->segs_clean[((nextop&0x38)>>3)] = 0;
emu->segs_serial[((nextop&0x38)>>3)] = 0;
NEXT;
_66_0x8F: /* POP Ew */
nextop = F8;
@@ -355,6 +356,7 @@
Run66D9(emu);
ip = R_EIP;
if(emu->quit) goto fini;
STEP
NEXT;
_66_0xDD:
@@ -363,8 +365,17 @@
Run66DD(emu);
ip = R_EIP;
if(emu->quit) goto fini;
STEP
NEXT;
_66_0xF0: /* LOCK prefix */
emu->old_ip = R_EIP;
R_EIP = ip;
RunLock66(emu);
ip = R_EIP;
if(emu->quit) goto fini;
STEP
NEXT;
_66_0xF2: /* REPNZ prefix */
_66_0xF3: /* REPZ prefix */
+2 -2
View File
@@ -111,7 +111,7 @@
break;
case 2: /* FIST Ed, ST0 */
GET_ED;
if(isgreater(ST0.d, (double)(int32_t)0x7fffffff) || isless(ST0.d, -(double)(int32_t)0x7fffffff))
if(isgreater(ST0.d, (double)(int32_t)0x7fffffff) || isless(ST0.d, -(double)(int32_t)0x7fffffff) || !isfinite(ST0.d))
ED->sdword[0] = 0x80000000;
else {
volatile int32_t tmp = fpu_round(emu, ST0.d); // tmp to avoid BUS ERROR
@@ -120,7 +120,7 @@
break;
case 3: /* FISTP Ed, ST0 */
GET_ED;
if(isgreater(ST0.d, (double)(int32_t)0x7fffffff) || isless(ST0.d, -(double)(int32_t)0x7fffffff))
if(isgreater(ST0.d, (double)(int32_t)0x7fffffff) || isless(ST0.d, -(double)(int32_t)0x7fffffff) || !isfinite(ST0.d))
ED->sdword[0] = 0x80000000;
else {
volatile int32_t tmp = fpu_round(emu, ST0.d); // tmp to avoid BUS ERROR
+23 -25
View File
@@ -98,28 +98,14 @@
break;
case 2: /* FIST Ew, ST0 */
GET_EW;
if(isgreater(ST0.d, (double)(int32_t)0x7fff) || isless(ST0.d, -(double)(int32_t)0x7fff))
if(isgreater(ST0.d, (double)(int32_t)0x7fff) || isless(ST0.d, -(double)(int32_t)0x7fff) || !isfinite(ST0.d))
EW->sword[0] = 0x8000;
else {
switch(emu->round) {
case ROUND_Nearest:
EW->sword[0] = floor(ST0.d+0.5);
break;
case ROUND_Down:
EW->sword[0] = floor(ST0.d);
break;
case ROUND_Up:
EW->sword[0] = ceil(ST0.d);
break;
case ROUND_Chop:
EW->sword[0] = ST0.d;
break;
}
}
else
EW->sword[0] = fpu_round(emu, ST0.d);
break;
case 3: /* FISTP Ew, ST0 */
GET_EW;
if(isgreater(ST0.d, (double)(int32_t)0x7fff) || isless(ST0.d, -(double)(int32_t)0x7fff))
if(isgreater(ST0.d, (double)(int32_t)0x7fff) || isless(ST0.d, -(double)(int32_t)0x7fff) || !isfinite(ST0.d))
EW->sword[0] = 0x8000;
else
EW->sword[0] = fpu_round(emu, ST0.d);
@@ -145,14 +131,26 @@
break;
case 7: /* FISTP i64 */
GET_ED;
if(STll(0).ref==ST(0).ll) {
*(int64_t*)ED = STll(0).ll;
} else {
if(isgreater(ST0.d, (double)(int64_t)0x7fffffffffffffffLL) || isless(ST0.d, -(double)(int64_t)0x7fffffffffffffffLL))
*(int64_t*)ED = 0x8000000000000000LL;
if((uintptr_t)ED & 0x7) {
// un-aligned!
if(STll(0).ref==ST(0).ll)
memcpy(ED, &STll(0).ll, sizeof(int64_t));
else {
int64_t i64 = fpu_round(emu, ST0.d);
*(int64_t*)ED = i64;
int64_t i64;
if(isgreater(ST0.d, (double)(int64_t)0x7fffffffffffffffLL) || isless(ST0.d, -(double)(int64_t)0x7fffffffffffffffLL) || !isfinite(ST0.d))
i64 = 0x8000000000000000LL;
else
i64 = fpu_round(emu, ST0.d);
memcpy(ED, &i64, sizeof(int64_t));
}
} else {
if(STll(0).ref==ST(0).ll)
*(int64_t*)ED = STll(0).ll;
else {
if(isgreater(ST0.d, (double)(int64_t)0x7fffffffffffffffLL) || isless(ST0.d, -(double)(int64_t)0x7fffffffffffffffLL) || !isfinite(ST0.d))
*(int64_t*)ED = 0x8000000000000000LL;
else
*(int64_t*)ED = fpu_round(emu, ST0.d);
}
}
fpu_do_pop(emu);
+9
View File
@@ -230,6 +230,15 @@
GX.q[0]=(tmp8s)?0xffffffffffffffffLL:0LL;
break;
case 0xD0: /* ADDSUBPS Gx, Ex */
nextop = F8;
GET_EX;
GX.f[0] -= EX->f[0];
GX.f[1] += EX->f[1];
GX.f[2] -= EX->f[2];
GX.f[3] += EX->f[3];
break;
case 0xD6: /* MOVDQ2Q Gm, Ex */
nextop = F8;
GET_EX;
+13
View File
@@ -15,6 +15,19 @@
GET_EX;
EX->ud[0] = GX.ud[0];
break;
case 0x12: /* MOVSLDUP Gx, Ex */
nextop = F8;
GET_EX;
GX.ud[1] = GX.ud[0] = EX->ud[0];
GX.ud[3] = GX.ud[2] = EX->ud[2];
break;
case 0x16: /* MOVSHDUP Gx, Ex */
nextop = F8;
GET_EX;
GX.ud[1] = GX.ud[0] = EX->ud[1];
GX.ud[3] = GX.ud[2] = EX->ud[3];
break;
case 0x1E: /* NOP / ENDBR32 / ENDBR64 */
nextop = F8;
+15 -1
View File
@@ -35,6 +35,13 @@ static uint32_t x86emu_parity_tab[8] =
};
static uint8_t EndEmuMarker[] = {0xcc, 'S', 'C', 0, 0, 0, 0};
#ifdef DYNAREC
void DynablockEmuMarker(box86context_t* context)
{
dynarec_log(LOG_DUMP, "Create bridge memory map for PushExit\n");
addDBFromAddressRange(context, (uintptr_t)&EndEmuMarker[0], sizeof(EndEmuMarker), 0);
}
#endif
void PushExit(x86emu_t* emu)
{
Push(emu, (uint32_t)&EndEmuMarker);
@@ -195,7 +202,7 @@ void CloneEmu(x86emu_t *newemu, const x86emu_t* emu)
memcpy(&newemu->flags, &emu->flags, sizeof(emu->flags));
newemu->old_ip = emu->old_ip;
memcpy(newemu->segs, emu->segs, sizeof(emu->segs));
memset(newemu->segs_clean, 0, sizeof(newemu->segs_clean));
memset(newemu->segs_serial, 0, sizeof(newemu->segs_serial));
memcpy(newemu->fpu, emu->fpu, sizeof(emu->fpu));
memcpy(newemu->fpu_ld, emu->fpu_ld, sizeof(emu->fpu_ld));
memcpy(newemu->fpu_ll, emu->fpu_ll, sizeof(emu->fpu_ll));
@@ -460,3 +467,10 @@ uint64_t ReadTSC(x86emu_t* emu)
return (uint64_t)(tv.tv_sec) * 1000000 + tv.tv_usec;
#endif
}
void ResetSegmentsCache(x86emu_t *emu)
{
if(!emu)
return;
memset(emu->segs_serial, 0, sizeof(emu->segs_serial));
}
+4 -3
View File
@@ -56,7 +56,7 @@ typedef struct x86emu_s {
// segments
uint32_t segs[6]; // only 32bits value?
uintptr_t segs_offs[6]; // computed offset associate with segment
int segs_clean[6]; // are seg offset clean (1) or does they need to be re-computed (0)?
uint32_t segs_serial[6]; // are seg offset clean (not 0) or does they need to be re-computed (0)? For GS, serial need to be the same as context->sel_serial
// emu control
int quit;
int error;
@@ -65,12 +65,13 @@ typedef struct x86emu_s {
int exit;
int quitonlongjmp; // quit if longjmp is called
int longjmp; // if quit because of longjmp
// parent context
box86context_t *context;
#ifdef DYNAREC
// virtual return stack
int cstacki; // current index
uint64_t cstack[CSTACK+1]; // pair of x86 address / native address for call/ret, using uint64_t for alignement, +1 for allignment
#endif
// parent context
box86context_t *context;
// cpu helpers
reg32_t zero;
reg32_t *sbiidx[8];
+26 -1
View File
@@ -1,3 +1,5 @@
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <dlfcn.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -67,6 +69,9 @@ void x86Int3(x86emu_t* emu)
if(Peek(emu, 0)=='S' && Peek(emu, 1)=='C') // Signature for "Out of x86 door"
{
R_EIP += 2;
#ifdef RK3399
volatile // to avoid addr to be put in an VFPU register
#endif
uint32_t addr = Fetch32(emu);
if(addr==0) {
//printf_log(LOG_INFO, "%p:Exit x86 emu (emu=%p)\n", *(void**)(R_ESP), emu);
@@ -89,7 +94,13 @@ void x86Int3(x86emu_t* emu)
int post = 0;
int perr = 0;
uint32_t *pu32 = NULL;
const char *s = GetNativeName((void*)addr);
const char *s = NULL;
{
Dl_info info;
if(dladdr((void*)addr, &info))
s = info.dli_sname;
}
if(!s) s = GetNativeName((void*)addr);
if(addr==(uintptr_t)PltResolver) {
snprintf(buff, 256, "%s", " ... ");
} else
@@ -113,9 +124,16 @@ void x86Int3(x86emu_t* emu)
tmp = *(char**)(R_ESP+4);
snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", %d (,%d))", tid, *(void**)(R_ESP), s, (tmp)?tmp:"(nil)", *(int*)(R_ESP+8), *(int*)(R_ESP+12));
perr = 1;
} else if(strcmp(s, "mkdir")==0) {
tmp = *(char**)(R_ESP+4);
snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", %d)", tid, *(void**)(R_ESP), s, (tmp)?tmp:"(nil)", *(int*)(R_ESP+8));
perr = 1;
} else if(!strcmp(s, "fopen")) {
snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\")", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4), *(char**)(R_ESP+8));
perr = 1;
} else if(!strcmp(s, "freopen")) {
snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\", %p)", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4), *(char**)(R_ESP+8), *(void**)(R_ESP+12));
perr = 1;
} else if(!strcmp(s, "fopen64")) {
snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\")", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4), *(char**)(R_ESP+8));
perr = 2;
@@ -140,6 +158,9 @@ void x86Int3(x86emu_t* emu)
} else if(strstr(s, "__xstat64")==s) {
snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p(\"%s\"), %p)", tid, *(void**)(R_ESP), s, *(int32_t*)(R_ESP+4), *(char**)(R_ESP+8), *(char**)(R_ESP+8), *(void**)(R_ESP+12));
perr = 1;
} else if(strcmp(s, "__xstat")==0) {
snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p(\"%s\"), %p)", tid, *(void**)(R_ESP), s, *(int32_t*)(R_ESP+4), *(char**)(R_ESP+8), *(char**)(R_ESP+8), *(void**)(R_ESP+12));
perr = 1;
} else if(strstr(s, "__lxstat64")==s) {
snprintf(buff, 255, "%04d|%p: Calling %s(%d, %p(\"%s\"), %p)", tid, *(void**)(R_ESP), s, *(int32_t*)(R_ESP+4), *(char**)(R_ESP+8), *(char**)(R_ESP+8), *(void**)(R_ESP+12));
perr = 1;
@@ -200,6 +221,10 @@ void x86Int3(x86emu_t* emu)
snprintf(buff, 255, "%04d|%p: Calling %s(%08X, \"%s\", ...)", tid, *(void**)(R_ESP), s, *(uint32_t*)(R_ESP+4), pu32?((char*)(pu32)):"nil");
} else if(strstr(s, "vfprintf")==s) {
snprintf(buff, 255, "%04d|%p: Calling %s(%08X, \"%s\", ...)", tid, *(void**)(R_ESP), s, *(uint32_t*)(R_ESP+4), *(char**)(R_ESP+8));
} else if(strstr(s, "vkGetInstanceProcAddr")==s) {
snprintf(buff, 255, "%04d|%p: Calling %s(%p, \"%s\")", tid, *(void**)(R_ESP), s, *(void**)(R_ESP+4), *(char**)(R_ESP+8));
} else if(strstr(s, "vkGetDeviceProcAddr")==s) {
snprintf(buff, 255, "%04d|%p: Calling %s(%p, \"%s\")", tid, *(void**)(R_ESP), s, *(void**)(R_ESP+4), *(char**)(R_ESP+8));
} else if(strstr(s, "sscanf")==s) {
snprintf(buff, 255, "%04d|%p: Calling %s(\"%s\", \"%s\", ...)", tid, *(void**)(R_ESP), s, *(char**)(R_ESP+4), *(char**)(R_ESP+8));
} else if(strstr(s, "XCreateWindow")==s) {
+37 -27
View File
@@ -19,6 +19,7 @@
#include "x87emu_private.h"
#include "box86context.h"
#include "my_cpuid.h"
#include "bridge.h"
#ifdef DYNAREC
#include "../dynarec/arm_lock_helper.h"
#endif
@@ -125,7 +126,7 @@ int Run(x86emu_t *emu, int step)
&&_0f_0xC0, &&_0f_0xC1, &&_0f_0xC2, &&_0f_0xC3, &&_0f_0xC4, &&_0f_0xC5, &&_0f_0xC6, &&_0f_0xC7,
&&_0f_0xC8, &&_0f_0xC9, &&_0f_0xCA, &&_0f_0xCB, &&_0f_0xCC, &&_0f_0xCD, &&_0f_0xCE, &&_0f_0xCF, //0xC8-0xCF
&&_default, &&_0f_0xD1, &&_0f_0xD2, &&_0f_0xD3, &&_0f_0xD4 ,&&_0f_0xD5, &&_default, &&_0f_0xD7, //0xD0-0xD7
&&_0f_0xD8, &&_0f_0xD9, &&_default, &&_0f_0xDB, &&_0f_0xDC ,&&_0f_0xDD, &&_default, &&_0f_0xDF, //0xD8-0xDF
&&_0f_0xD8, &&_0f_0xD9, &&_0f_0xDA, &&_0f_0xDB, &&_0f_0xDC ,&&_0f_0xDD, &&_0f_0xDE, &&_0f_0xDF, //0xD8-0xDF
&&_0f_0xE0, &&_0f_0xE1, &&_0f_0xE2, &&_0f_0xE3, &&_0f_0xE4 ,&&_0f_0xE5, &&_default, &&_0f_0xE7, //0xE0-0xE7
&&_0f_0xE8, &&_0f_0xE9, &&_0f_0xEA, &&_0f_0xEB, &&_0f_0xEC ,&&_0f_0xED, &&_0f_0xEE, &&_0f_0xEF, //0xE8-0xEF
&&_default, &&_0f_0xF1, &&_0f_0xF2, &&_0f_0xF3, &&_0f_0xF4 ,&&_0f_0xF5, &&_0f_0xF6, &&_0f_0xF7, //0xF0-0xF7
@@ -163,7 +164,7 @@ int Run(x86emu_t *emu, int step)
&&_default, &&_66_0xD9, &&_default, &&_default, &&_default ,&&_66_0xDD, &&_default, &&_default, //0xD8-0xDF
&&_default, &&_default, &&_default, &&_default, &&_default ,&&_default, &&_default, &&_default, //0xE0-0xE7
&&_default, &&_default, &&_default, &&_default, &&_default ,&&_default, &&_default, &&_default, //0xE8-0xEF
&&_default, &&_default, &&_66_0xF2, &&_66_0xF3, &&_default, &&_default, &&_default, &&_66_0xF7,
&&_66_0xF0, &&_default, &&_66_0xF2, &&_66_0xF3, &&_default, &&_default, &&_default, &&_66_0xF7,
&&_66_0xF8, &&_66_0xF9, &&_default, &&_default, &&_default, &&_default, &&_default, &&_66_0xFF
};
@@ -262,7 +263,7 @@ _trace:
NEXT;
_0x07: /* POP ES */
emu->segs[_ES] = Pop(emu); // no check, no use....
emu->segs_clean[_ES] = 0;
emu->segs_serial[_ES] = 0;
NEXT;
_0x0E: /* PUSH CS */
@@ -277,7 +278,7 @@ _trace:
NEXT;
_0x17: /* POP SS */
emu->segs[_SS] = Pop(emu); // no check, no use....
emu->segs_clean[_SS] = 0;
emu->segs_serial[_SS] = 0;
NEXT;
_0x1E: /* PUSH DS */
@@ -285,7 +286,7 @@ _trace:
NEXT;
_0x1F: /* POP DS */
emu->segs[_DS] = Pop(emu); // no check, no use....
emu->segs_clean[_DS] = 0;
emu->segs_serial[_DS] = 0;
NEXT;
_0x26: /* ES: */
@@ -398,6 +399,7 @@ _trace:
RunFS(emu); // implemented in Run66.c
ip = R_EIP;
if(emu->quit) goto fini;
STEP
NEXT;
_0x65: /* GS: */
emu->old_ip = R_EIP;
@@ -405,6 +407,7 @@ _trace:
RunGS(emu); // implemented in Run66.c
ip = R_EIP;
if(emu->quit) goto fini;
STEP
NEXT;
_0x66: /* Prefix to change width of intructions, so here, down to 16bits */
@@ -415,6 +418,7 @@ _trace:
Run67(emu); // implemented in Run66.c
ip = R_EIP;
if(emu->quit) goto fini;
STEP
NEXT;
_0x68: /* Push Id */
@@ -641,13 +645,11 @@ _trace:
// not aligned, dont't try to "LOCK"
tmp32u = ED->dword[0];
ED->dword[0] = GD.dword[0];
GD.dword[0] = tmp32u;
} else {
// XCHG is supposed to automaticaly LOCK memory bus
do {
tmp32u = arm_lock_read_d(ED);
} while(arm_lock_write_d(ED, GD.dword[0]));
GD.dword[0] = arm_lock_xchg(ED, GD.dword[0]);
}
GD.dword[0] = tmp32u;
}
#else
GET_ED;
@@ -694,7 +696,9 @@ _trace:
nextop = F8;
GET_EW;
emu->segs[((nextop&0x38)>>3)] = EW->word[0];
emu->segs_clean[((nextop&0x38)>>3)] = 0;
emu->segs_serial[((nextop&0x38)>>3)] = 0;
if(((nextop&0x38)>>3)==_FS)
default_fs = EW->word[0];
NEXT;
_0x8F: /* POP Ed */
nextop = F8;
@@ -893,14 +897,14 @@ _trace:
nextop = F8;
GET_ED;
emu->segs[_ES] = ED->word[0];
emu->segs_clean[_ES] = 0;
emu->segs_serial[_ES] = 0;
GD.dword[0] = *(uint32_t*)(((void*)ED)+2);
NEXT;
_0xC5: /* LDS Gd,Ed */
nextop = F8;
GET_ED;
emu->segs[_DS] = ED->word[0];
emu->segs_clean[_DS] = 0;
emu->segs_serial[_DS] = 0;
GD.dword[0] = *(uint32_t*)(((void*)ED)+2);
NEXT;
_0xC6: /* MOV Eb,Ib */
@@ -938,7 +942,7 @@ _trace:
_0xCB: /* FAR RET */
ip = Pop(emu);
emu->segs[_CS] = Pop(emu); // no check, no use....
emu->segs_clean[_CS] = 0;
emu->segs_serial[_CS] = 0;
// need to check status of CS register!
STEP
NEXT;
@@ -971,7 +975,7 @@ _trace:
_0xCF: /* IRET */
ip = Pop(emu);
emu->segs[_CS] = Pop(emu);
emu->segs_clean[_CS] = 0;
emu->segs_serial[_CS] = 0;
emu->packed_eflags.x32 = ((Pop(emu) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1
UnpackFlags(emu);
RESET_FLAGS(emu);
@@ -1053,6 +1057,7 @@ _trace:
--R_ECX; // don't update flags
if(R_ECX && !ACCESS_FLAG(F_ZF))
ip += tmp8s;
STEP
NEXT;
_0xE1: /* LOOPZ */
CHECK_FLAGS(emu);
@@ -1060,19 +1065,20 @@ _trace:
--R_ECX; // don't update flags
if(R_ECX && ACCESS_FLAG(F_ZF))
ip += tmp8s;
STEP
NEXT;
_0xE2: /* LOOP */
tmp8s = F8S;
--R_ECX; // don't update flags
if(R_ECX)
ip += tmp8s;
STEP
NEXT;
_0xE3: /* JECXZ */
tmp8s = F8S;
if(!R_ECX) {
if(!R_ECX)
ip += tmp8s;
STEP
}
STEP
NEXT;
_0xE4: /* IN AL, Ib */
tmp32s = F8; // port address
@@ -1133,6 +1139,7 @@ _trace:
} else {
#include "runf20f.h"
}
STEP
NEXT;
} else if(nextop==0x66) {
nextop = F8;
@@ -1500,6 +1507,7 @@ _trace:
NEXT;
_0xFE: /* GRP 5 Eb */
nextop = F8;
tmp32u2 = ip;
GET_EB;
switch((nextop>>3)&7) {
case 0: /* INC Eb */
@@ -1510,8 +1518,8 @@ _trace:
break;
default:
emu->old_ip = R_EIP;
R_EIP = ip;
printf_log(LOG_NONE, "Illegal Opcode %02X %02X\n", opcode, nextop);
R_EIP = ip = tmp32u2;
printf_log(LOG_NONE, "Illegal Opcode %p: %02X %02X %02X %02X\n", (void*)ip, opcode, nextop, PK(2), PK(3));
emu->quit=1;
emu->error |= ERR_ILLEGAL;
goto fini;
@@ -1519,6 +1527,7 @@ _trace:
NEXT;
_0xFF: /* GRP 5 Ed */
nextop = F8;
tmp32u2 = ip;
GET_ED;
switch((nextop>>3)&7) {
case 0: /* INC Ed */
@@ -1528,15 +1537,16 @@ _trace:
ED->dword[0] = dec32(emu, ED->dword[0]);
break;
case 2: /* CALL NEAR Ed */
tmp32u = (uintptr_t)getAlternate((void*)ED->dword[0]);
Push(emu, ip);
ip = ED->dword[0]; // should get value in temp var. in case ED use ESP?
ip = tmp32u;
STEP
break;
case 3: /* CALL FAR Ed */
if(nextop>0xc0) {
emu->old_ip = R_EIP;
R_EIP = ip;
printf_log(LOG_NONE, "Illegal Opcode %02X %02X\n", opcode, nextop);
R_EIP = ip = tmp32u2;
printf_log(LOG_NONE, "Illegal Opcode %p: %02X %02X %02X %02X\n", (void*)ip, opcode, nextop, PK(2), PK(3));
emu->quit=1;
emu->error |= ERR_ILLEGAL;
goto fini;
@@ -1549,14 +1559,14 @@ _trace:
}
break;
case 4: /* JMP NEAR Ed */
ip = ED->dword[0];
ip = (uintptr_t)getAlternate((void*)ED->dword[0]);
STEP
break;
case 5: /* JMP FAR Ed */
if(nextop>0xc0) {
emu->old_ip = R_EIP;
R_EIP = ip;
printf_log(LOG_NONE, "Illegal Opcode 0x%02X 0x%02X\n", opcode, nextop);
R_EIP = ip = tmp32u2;
printf_log(LOG_NONE, "Illegal Opcode %p: 0x%02X 0x%02X %02X %02X\n", (void*)ip, opcode, nextop, PK(2), PK(3));
emu->quit=1;
emu->error |= ERR_ILLEGAL;
goto fini;
@@ -1572,8 +1582,8 @@ _trace:
break;
default:
emu->old_ip = R_EIP;
R_EIP = ip;
printf_log(LOG_NONE, "Illegal Opcode %02X %02X %02X %02X %02X %02X\n", opcode, nextop, PK(2), PK(3), PK(4), PK(5));
R_EIP = ip = tmp32u2;
printf_log(LOG_NONE, "Illegal Opcode %p: %02X %02X %02X %02X %02X %02X\n",(void*)ip, opcode, nextop, PK(2), PK(3), PK(4), PK(5));
emu->quit=1;
emu->error |= ERR_ILLEGAL;
goto fini;
+126
View File
@@ -473,6 +473,32 @@ void RunLock(x86emu_t *emu)
nextop = F8;
GET_ED;
#ifdef DYNAREC
if(((uintptr_t)ED)&7) {
// unaligned!!!
uint64_t ref = R_EDX;
ref = ref<<32 | R_EAX;
void* p = (void*)(((uintptr_t)ED + 3)&~3);
int d = (((uintptr_t)p - (uintptr_t)ED))*8;
do {
uint64_t m = *(uint64_t*)ED;
m&=~((0xffffffffLL)<<d);
tmp32u = arm_lock_read_d(p);
m|=((uint64_t)tmp32u)<<d;
if(ref == m) {
SET_FLAG(F_ZF);
m = ((uint64_t)R_ECX)<<32 | R_EBX;
tmp32u2 = m>>d;
tmp32s = arm_lock_write_d(p, tmp32u2);
if(!tmp32s)
*(uint64_t*)ED = m;
} else {
CLEAR_FLAG(F_ZF);
R_EAX = m&0xffffffff;
R_EDX = m>>32;
tmp32s = 0;
}
} while(tmp32s);
} else
do {
arm_lock_read_dd(&tmp32u, &tmp32u2, ED);
if(R_EAX == tmp32u && R_EDX == tmp32u2) {
@@ -547,6 +573,16 @@ void RunLock(x86emu_t *emu)
case 0x87: /* XCHG Ed,Gd */
ip--; // let the normal XCHG execute, it have integrated LOCK
break;
case 0x90: // This is xchg reg, reg, so let's ignore the LOCK prefix...
case 0x91:
case 0x92:
case 0x93:
case 0x94:
case 0x95:
case 0x96:
case 0x97:
ip--;
break;
case 0xFF: /* GRP 5 Ed */
nextop = F8;
GET_ED;
@@ -588,6 +624,57 @@ void RunLock(x86emu_t *emu)
R_EIP = ip;
}
void RunLock66(x86emu_t *emu)
{
uintptr_t ip = R_EIP+1;
uint8_t opcode = F8;
uint8_t nextop;
reg32_t *oped;
uint16_t tmp16u;
int32_t tmp32s;
switch(opcode) {
case 0x0f:
opcode = F8;
switch (opcode) {
case 0xB1: /* CMPXCHG Ew,Gw */
nextop = F8;
GET_EW;
#ifdef DYNAREC
do {
tmp16u = arm_lock_read_h(ED);
cmp16(emu, R_AX, tmp16u);
if(ACCESS_FLAG(F_ZF)) {
tmp32s = arm_lock_write_h(ED, GW.word[0]);
} else {
R_AX = tmp16u;
tmp32s = 0;
}
} while(tmp32s);
#else
pthread_mutex_lock(&emu->context->mutex_lock);
GET_EW;
cmp16(emu, R_AX, EW->word[0]);
if(ACCESS_FLAG(F_ZF)) {
EW->word[0] = GW.word[0];
} else {
R_AX = EW->word[0];
}
pthread_mutex_unlock(&emu->context->mutex_lock);
#endif
break;
default:
ip-=4; // unfetch nextop, 0F, F0 & 66
UnimpOpcode(emu);
}
break;
default:
ip-=3; // unfetch nextop, F0 & 66
UnimpOpcode(emu);
// should trigger invalid unlock ?
}
R_EIP = ip;
}
void RunGS(x86emu_t *emu)
{
uintptr_t ip = R_EIP+1;
@@ -823,6 +910,29 @@ void RunFS(x86emu_t *emu)
int32_t tmp32s;
uintptr_t tlsdata = GetFSBaseEmu(emu);
switch(opcode) {
case 0x01: /* ADD FS:Ed, Gd */
nextop = F8;
GET_ED_OFFS(tlsdata);
ED->dword[0] = add32(emu, ED->dword[0], GD.dword[0]);
break;
case 0x03: /* ADD Gd, FS:Ed */
nextop = F8;
GET_ED_OFFS(tlsdata);
GD.dword[0] = add32(emu, GD.dword[0], ED->dword[0]);
break;
case 0x11: /* ADC FS:Ed, Gd */
nextop = F8;
GET_ED_OFFS(tlsdata);
ED->dword[0] = adc32(emu, ED->dword[0], GD.dword[0]);
case 0x2B: /* SUB Gd, FS:Ed */
nextop = F8;
GET_ED_OFFS(tlsdata);
GD.dword[0] = sub32(emu, GD.dword[0], ED->dword[0]);
break;
case 0x33: /* XOR Gd,Ed */
nextop = F8;
GET_ED_OFFS(tlsdata);
@@ -953,11 +1063,27 @@ void RunFS(x86emu_t *emu)
GET_ED_OFFS(tlsdata);
GD.dword[0] = ED->dword[0];
break;
case 0x8C: /* MOV FS:Ed, Seg */
nextop = F8;
GET_ED_OFFS(tlsdata);
ED->dword[0] = emu->segs[((nextop&0x38)>>3)];
break;
case 0x8E: /* MOV Seg,FS:Ed */
nextop = F8;
GET_ED_OFFS(tlsdata);
emu->segs[((nextop&0x38)>>3)] = ED->word[0];
emu->segs_serial[((nextop&0x38)>>3)] = 0;
break;
case 0x8F: /* POP Ed */
nextop = F8;
GET_ED_OFFS(tlsdata);
ED->dword[0] = Pop(emu);
break;
case 0xA0: /* MOV AL,Ob */
tmp32s = F32S;
R_AL = *(uint8_t*)((tlsdata) + tmp32s);
break;
case 0xA1: /* MOV EAX,Ov */
tmp32s = F32S;
R_EAX = *(uint32_t*)((tlsdata) + tmp32s);
+14 -12
View File
@@ -56,23 +56,24 @@ int32_t EXPORT my___libc_start_main(x86emu_t* emu, int *(main) (int, char * *, c
const char* GetNativeName(void* p)
{
static char unknown[10] = "???";
const char *ret = GetNameOffset(my_context->maplib, p);
if(ret)
return ret;
static char buff[500] = {0};
Dl_info info;
if(dladdr(p, &info)==0)
return unknown;
else {
if(dladdr(p, &info)==0) {
const char *ret = GetNameOffset(my_context->maplib, p);
if(ret)
return ret;
sprintf(buff, "%s(%p)", "???", p);
return buff;
} else {
if(info.dli_sname) {
strcpy(buff, info.dli_sname);
if(info.dli_fname) {
strcat(buff, " ("); strcat(buff, info.dli_fname); strcat(buff, ")");
}
} else
return unknown;
} else {
sprintf(buff, "%s(%s/%p)", "???", info.dli_fname, p);
return buff;
}
}
return buff;
}
@@ -744,9 +745,9 @@ void UnpackFlags(x86emu_t* emu)
uintptr_t GetSegmentBaseEmu(x86emu_t* emu, int seg)
{
if(!emu->segs_clean[seg] || seg==_GS) {
if(emu->segs_serial[seg] != emu->context->sel_serial) {
emu->segs_offs[seg] = (uintptr_t)GetSegmentBase(emu->segs[seg]);
emu->segs_clean[seg] = 1;
emu->segs_serial[seg] = emu->context->sel_serial;
}
return emu->segs_offs[seg];
}
@@ -806,6 +807,7 @@ void PrintTrace(x86emu_t* emu, uintptr_t ip, int dynarec)
my_context->trace_tid = tid;
}
#endif
trace_end = 0;
printf_log(LOG_NONE, "%s", DumpCPURegs(emu, ip));
if(PK(0)==0xcc && PK(1)=='S' && PK(2)=='C') {
uint32_t a = *(uint32_t*)(ip+3);
+1
View File
@@ -202,6 +202,7 @@ void Run6766(x86emu_t *emu);
void RunGS(x86emu_t *emu);
void RunFS(x86emu_t *emu);
void RunLock(x86emu_t *emu);
void RunLock66(x86emu_t *emu);
void x86Syscall(x86emu_t *emu);
void x86Int3(x86emu_t* emu);
+19 -1
View File
@@ -56,6 +56,9 @@ typedef struct x86_sigaction_s x86_sigaction_t;
int32_t my_getrandom(x86emu_t* emu, void* buf, uint32_t buflen, uint32_t flags);
int of_convert(int flag);
int32_t my_open(x86emu_t* emu, void* pathname, int32_t flags, uint32_t mode);
#ifndef __NR_memfd_create
int my_memfd_create(x86emu_t* emu, void* name, uint32_t flags);
#endif
#ifndef NOALIGN
int my_epoll_create(x86emu_t* emu, int size);
@@ -200,6 +203,8 @@ scwrap_t syscallwrap[] = {
//{ 221, __NR_fcntl64, 3 },
{ 224, __NR_gettid, 0 },
{ 240, __NR_futex, 6 },
{ 241, __NR_sched_setaffinity, 3 },
{ 242, __NR_sched_getaffinity, 3 },
{ 252, __NR_exit_group, 1 },
#ifdef NOALIGN
{ 254, __NR_epoll_create, 1 },
@@ -218,6 +223,9 @@ scwrap_t syscallwrap[] = {
#ifdef __NR_getrandom
{ 355, __NR_getrandom, 3 },
#endif
#ifdef __NR_memfd_create
{ 356, __NR_memfd_create, 2},
#endif
};
struct mmap_arg_struct {
@@ -323,7 +331,8 @@ void EXPORT x86Syscall(x86emu_t *emu)
case 1: // sys_exit
emu->quit = 1;
emu->exit = 1;
R_EAX = R_EBX; // faking the syscall here, we don't want to really terminate the program now
//R_EAX = syscall(__NR_exit, R_EBX); // the syscall should exit only current thread
R_EAX = R_EBX; // faking the syscall here, we don't want to really terminate the thread now
break;
case 3: // sys_read
R_EAX = (uint32_t)read((int)R_EBX, (void*)R_ECX, (size_t)R_EDX);
@@ -577,6 +586,11 @@ void EXPORT x86Syscall(x86emu_t *emu)
case 355: // getrandom
R_EAX = my_getrandom(emu, (void*)R_EBX, R_ECX, R_EDX);
break;
#endif
#ifndef __NR_memfd_create
case 356: // memfd_create
R_EAX = my_memfd_create(emu, (void*)R_EBX, R_ECX);
break;
#endif
default:
printf_log(LOG_INFO, "Error: Unsupported Syscall 0x%02Xh (%d)\n", s, s);
@@ -661,6 +675,10 @@ uint32_t EXPORT my_syscall(x86emu_t *emu)
#ifndef __NR_getrandom
case 355: // getrandom
return (uint32_t)my_getrandom(emu, p(4), u32(8), u32(12));
#endif
#ifndef __NR_memfd_create
case 356: // memfd_create
return (uint32_t)my_memfd_create(emu, (void*)R_EBX, R_ECX);
#endif
default:
printf_log(LOG_INFO, "Error: Unsupported libc Syscall 0x%02X (%d)\n", s, s);
+4
View File
@@ -89,6 +89,8 @@ uint32_t my_set_thread_area(thread_area_t* td)
pthread_setspecific(my_context->segtls[idx-7].key, (void*)my_context->segtls[idx-7].base);
ResetSegmentsCache(thread_get_emu());
return 0;
}
@@ -120,6 +122,8 @@ uint32_t my_modify_ldt(x86emu_t* emu, int op, thread_area_t* td, int size)
my_context->segtls[idx].limit = td->limit;
pthread_setspecific(my_context->segtls[idx].key, (void*)my_context->segtls[idx].base);
*/
ResetSegmentsCache(thread_get_emu());
return 0;
}
+32 -16
View File
@@ -16,11 +16,21 @@
#include "x86trace.h"
#include "x86run.h"
#define F8 *(uint8_t*)(ip++)
#define F8S *(int8_t*)(ip++)
#define F16 *(uint16_t*)(ip+=2, ip-2)
#define F16S *(int16_t*)(ip+=2, ip-2)
#define F32 *(uint32_t*)(ip+=4, ip-4)
#define F32S *(int32_t*)(ip+=4, ip-4)
#define PK(a) *(uint8_t*)(ip+a)
#include "modrm.h"
void Run66D9(x86emu_t *emu)
{
uint8_t nextop;
reg32_t *op1;
nextop = Fetch8(emu);
uintptr_t ip = R_EIP;
uint8_t nextop = F8;
reg32_t *oped;
switch (nextop) {
case 0xC0:
case 0xC1:
@@ -66,31 +76,34 @@ void Run66D9(x86emu_t *emu)
case 0xFD:
case 0xFE:
case 0xFF:
ip = R_EIP-2;
UnimpOpcode(emu);
break;
default:
switch((nextop>>3)&7) {
case 4: /* FLDENV m */
// warning, incomplete
op1=GetEw(emu, nextop);
fpu_loadenv(emu, (char*)op1, 1);
GET_EW;
fpu_loadenv(emu, (char*)ED, 1);
break;
case 6: /* FNSTENV m */
// warning, incomplete
op1=GetEw(emu, nextop);
fpu_savenv(emu, (char*)op1, 1);
GET_EW;
fpu_savenv(emu, (char*)ED, 1);
break;
default:
ip = R_EIP-2;
UnimpOpcode(emu);
}
}
R_EIP = ip;
}
void Run66DD(x86emu_t *emu)
{
uint8_t nextop;
reg32_t *op1;
nextop = Fetch8(emu);
uintptr_t ip = R_EIP;
uint8_t nextop = F8;
reg32_t *oped;
switch(nextop) {
case 0xC0:
@@ -137,17 +150,18 @@ void Run66DD(x86emu_t *emu)
case 0xFD:
case 0xFE:
case 0xFF:
ip = R_EIP-2;
UnimpOpcode(emu);
break;
default:
switch((nextop>>3)&7) {
case 4: /* FRSTOR m94byte */
op1=GetEw(emu, nextop);
fpu_loadenv(emu, (char*)op1, 1);
GET_EW;
fpu_loadenv(emu, (char*)ED, 1);
// get the STx
{
char* p =(char*)op1;
char* p =(char*)ED;
p += 14;
for (int i=0; i<8; ++i) {
LD2D(p, &ST(i).d);
@@ -156,12 +170,12 @@ void Run66DD(x86emu_t *emu)
}
break;
case 6: /* FNSAVE m94byte */
op1=GetEw(emu, nextop);
GET_EW;
// ENV first...
fpu_savenv(emu, (char*)op1, 1);
fpu_savenv(emu, (char*)ED, 1);
// save the STx
{
char* p =(char*)op1;
char* p =(char*)ED;
p += 14;
for (int i=0; i<8; ++i) {
D2LD(&ST(i).d, p);
@@ -171,7 +185,9 @@ void Run66DD(x86emu_t *emu)
reset_fpu(emu);
break;
default:
ip = R_EIP-2; // unfetch
UnimpOpcode(emu);
}
}
R_EIP = ip;
}
+28 -26
View File
@@ -12,7 +12,6 @@ typedef struct lib_s lib_t;
typedef struct bridge_s bridge_t;
typedef struct dlprivate_s dlprivate_t;
typedef struct kh_symbolmap_s kh_symbolmap_t;
typedef struct callbacklist_s callbacklist_t;
typedef struct library_s library_t;
typedef struct kh_fts_s kh_fts_t;
typedef struct kh_threadstack_s kh_threadstack_t;
@@ -25,16 +24,16 @@ typedef struct atfork_fnc_s {
void* handle;
} atfork_fnc_t;
#ifdef DYNAREC
typedef struct dynablocklist_s dynablocklist_t;
typedef struct mmaplist_s mmaplist_t;
typedef struct dynmap_s {
dynablocklist_t* dynablocks; // the dynabockist of the block
} dynmap_t;
typedef struct dynablock_s dynablock_t;
typedef struct dynablocklist_s dynablocklist_t;
typedef struct mmaplist_s mmaplist_t;
typedef struct kh_dynablocks_s kh_dynablocks_t;
#define DYNAMAP_SIZE (1<<20)
#define DYNAMAP_SHIFT 12
#endif
typedef void* (*procaddess_t)(const char* name);
typedef void* (*vkprocaddess_t)(void* instance, const char* name);
#define MAX_SIGNAL 64
@@ -62,6 +61,16 @@ typedef struct base_segment_s {
} base_segment_t;
typedef struct box86context_s {
#ifdef DYNAREC
dynablocklist_t** dynmap; // 4G of memory mapped by 4K block
int trace_dynarec;
pthread_mutex_t mutex_dyndump;
pthread_mutex_t mutex_blocks;
pthread_mutex_t mutex_mmap;
mmaplist_t *mmaplist;
int mmapsize;
kh_dynablocks_t *dblist_oversized; // store the list of oversized dynablocks (normal sized are inside mmaplist)
#endif
path_collection_t box86_path; // PATH env. variable
path_collection_t box86_ld_lib; // LD_LIBRARY_PATH env. variable
@@ -69,10 +78,9 @@ typedef struct box86context_s {
int x86trace;
int trace_tid;
#ifdef DYNAREC
int trace_dynarec;
pthread_mutex_t mutex_dyndump;
#endif
uint32_t sel_serial; // will be increment each time selectors changes
zydis_t *zydis; // dlopen the zydis dissasembler
void* box86lib; // dlopen on box86 itself
@@ -111,8 +119,9 @@ typedef struct box86context_s {
procaddess_t glxprocaddress;
kh_symbolmap_t *alwrappers; // the map of wrapper for alGetProcAddress
kh_symbolmap_t *almymap; // link to the mysymbolmap if libOpenAL
callbacklist_t *callbacks; // all callbacks
kh_symbolmap_t *vkwrappers; // the map of wrapper for VulkanProcs (TODO: check SDL2)
kh_symbolmap_t *vkmymap; // link to the mysymbolmap of libGL
vkprocaddess_t vkprocaddress;
pthread_mutex_t mutex_once;
pthread_mutex_t mutex_once2;
@@ -167,14 +176,6 @@ typedef struct box86context_s {
cleanup_t *cleanups; // atexit functions
int clean_sz;
int clean_cap;
#ifdef DYNAREC
pthread_mutex_t mutex_blocks;
pthread_mutex_t mutex_mmap;
dynablocklist_t *dynablocks;
mmaplist_t *mmaplist;
int mmapsize;
dynmap_t* dynmap[DYNAMAP_SIZE]; // 4G of memory mapped by 4K block
#endif
#ifndef NOALIGN
kh_fts_t *ftsmap;
#endif
@@ -190,6 +191,7 @@ typedef struct box86context_s {
uintptr_t signals[MAX_SIGNAL];
uintptr_t restorer[MAX_SIGNAL];
int onstack[MAX_SIGNAL];
int is_sigaction[MAX_SIGNAL];
x86emu_t *emu_sig; // the emu with stack used for signal handling (must be separated from main ones)
int no_sigsegv;
@@ -199,6 +201,8 @@ typedef struct box86context_s {
#endif
} box86context_t;
extern box86context_t *my_context; // global context
box86context_t *NewBox86Context(int argc);
void FreeBox86Context(box86context_t** context);
@@ -209,13 +213,11 @@ int AddElfHeader(box86context_t* ctx, elfheader_t* head);
int AddTLSPartition(box86context_t* context, int tlssize);
#ifdef DYNAREC
// the nolinker specified if static map or dynamic (can be deleted) has to be used
uintptr_t AllocDynarecMap(int size, int nolinker);
void FreeDynarecMap(uintptr_t addr, uint32_t size);
uintptr_t AllocDynarecMap(dynablock_t* db, int size);
void FreeDynarecMap(dynablock_t* db, uintptr_t addr, uint32_t size);
dynablocklist_t* getDBFromAddress(uintptr_t addr);
void addDBFromAddressRange(uintptr_t addr, uintptr_t size, int nolinker);
void cleanDBFromAddressRange(uintptr_t addr, uintptr_t size, int destroy);
void addDBFromAddressRange(box86context_t* context, uintptr_t addr, uintptr_t size, int nolinker);
void cleanDBFromAddressRange(box86context_t* context, uintptr_t addr, uintptr_t size, int destroy);
void protectDB(uintptr_t addr, uintptr_t size);
void unprotectDB(uintptr_t addr, uintptr_t size);
+9 -2
View File
@@ -4,15 +4,22 @@
typedef struct x86emu_s x86emu_t;
typedef struct bridge_s bridge_t;
typedef struct box86context_s box86context_t;
typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
bridge_t *NewBridge();
void FreeBridge(bridge_t** bridge);
uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N);
uintptr_t AddBridge(bridge_t* bridge, box86context_t* context, wrapper_t w, void* fnc, int N);
uintptr_t CheckBridged(bridge_t* bridge, void* fnc);
uintptr_t AddCheckBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N);
uintptr_t AddCheckBridge(bridge_t* bridge, box86context_t* context, wrapper_t w, void* fnc, int N);
uintptr_t AddAutomaticBridge(x86emu_t* emu, bridge_t* bridge, wrapper_t w, void* fnc, int N);
void* GetNativeFnc(uintptr_t fnc);
void* GetNativeFncOrFnc(uintptr_t fnc);
int hasAlternate(void* addr);
void* getAlternate(void* addr);
void addAlternate(void* addr, void* alt);
void cleanAlternate();
#endif //__BRIDGE_H_
-24
View File
@@ -3,36 +3,12 @@
#include <stdint.h>
typedef struct callbacklist_s callbacklist_t;
typedef struct x86emu_s x86emu_t;
callbacklist_t* NewCallbackList();
void FreeCallbackList(callbacklist_t** callbacks);
x86emu_t* AddCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
x86emu_t* AddVariableCallback(x86emu_t* emu, int stsize, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
x86emu_t* AddSmallCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
x86emu_t* AddSharedCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4);
x86emu_t* GetCallback1Arg(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1);
x86emu_t* FreeCallback(x86emu_t* emu);
uint32_t RunCallback(x86emu_t* emu);
void SetCallbackArg(x86emu_t* emu, int arg, void* val);
// set args starting from 0
void SetCallbackArgs(x86emu_t* emu, int nargs, ...);
// set args starting from N
void SetCallbackNArgs(x86emu_t* emu, int N, int nargs, ...);
void* GetCallbackArg(x86emu_t* emu, int arg);
void SetCallbackNArg(x86emu_t* emu, int narg);
void SetCallbackAddress(x86emu_t* emu, uintptr_t address);
uintptr_t GetCallbackAddress(x86emu_t* emu);
int IsCallback(box86context_t* context, x86emu_t* cb);
// use thread local emu to run the function (context is unused now)
uint32_t RunFunction(box86context_t *context, uintptr_t fnc, int nargs, ...);
// use thread local emu to run the function (context is unused now)
uint64_t RunFunction64(box86context_t *context, uintptr_t fnc, int nargs, ...);
// use emu state to run function
uint32_t RunFunctionWithEmu(x86emu_t *emu, int QuitOnLongJump, uintptr_t fnc, int nargs, ...);
// Find a cb using FNC address and argN as a key
x86emu_t* FindCallbackFnc1Arg(x86emu_t* emu, uintptr_t fnc, int argn, void* arg);
#endif //__CALLBACK_H__
+6 -4
View File
@@ -14,6 +14,7 @@ extern int box86_dynarec_trace;
extern int box86_dynarec_forced;
extern int box86_dynarec_largest;
extern int box86_dynarec_smc;
extern int box86_dynarec_safemmap;
#ifdef ARM
extern int arm_vfp; // vfp version (3 or 4), with 32 registers is mendatory
extern int arm_swap;
@@ -25,13 +26,14 @@ extern int trace_xmm; // include XMM reg in trace?
extern int trace_emm; // include EMM reg in trace?
extern int allow_missing_libs;
extern int box86_steam;
extern int box86_nopulse; // diabling the use of pulseaudio
extern int box86_nopulse; // diabling the use of wrapped pulseaudio
extern int box86_nogtk; // disabling the use of wrapped gtk
extern uintptr_t trace_start, trace_end;
extern box86context_t *my_context; // global context
extern char* trace_func;
extern uintptr_t fmod_smc_start, fmod_smc_end; // to handle libfmod (from Unreal) SMC (self modifying code)
extern uint16_t default_fs;
extern uint32_t default_fs;
extern int jit_gdb; // launch gdb when a segfault is trapped
extern int box86_tcmalloc_minimal; // when using tcmalloc_minimal
#define LOG_NONE 0
#define LOG_INFO 1
#define LOG_DEBUG 2
@@ -41,7 +43,7 @@ extern FILE* ftrace;
#define printf_log(L, ...) do {if(L<=box86_log) {fprintf(ftrace, __VA_ARGS__); fflush(ftrace);}} while(0)
#define dynarec_log(L, ...) do {if(L<=box86_dynarec_log) {fprintf(ftrace, __VA_ARGS__); fflush(ftrace);}} while(0)
#define dynarec_log(L, ...) do {if(L<=box86_dynarec_log) {fprintf(ftrace, __VA_ARGS__); /*fflush(ftrace);*/}} while(0)
#define EXPORT __attribute__((visibility("default")))
#ifdef BUILD_DYNAMIC
+6 -11
View File
@@ -2,10 +2,9 @@
#define __DYNABLOCK_H_
typedef struct x86emu_s x86emu_t;
typedef struct dynablock_s dynablock_t;
typedef struct dynablocklist_s dynablocklist_t;
typedef struct kh_dynablocks_s kh_dynablocks_t;
uint32_t X31_hash_code(void* addr, int len);
dynablocklist_t* NewDynablockList(uintptr_t base, uintptr_t text, int textsz, int nolinker, int direct);
@@ -14,13 +13,13 @@ void FreeDynablock(dynablock_t* db);
void MarkDynablock(dynablock_t* db);
void MarkDynablockList(dynablocklist_t** dynablocks);
void ProtectDynablock(dynablock_t* db);
void ProtectkDynablockList(dynablocklist_t** dynablocks);
void ProtectDynablockList(dynablocklist_t** dynablocks);
void ProtectDirectDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size);
void FreeRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size);
void MarkRangeDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t size);
// for debugging purpose
dynablock_t* FindDynablockFromNativeAddress(void* addr);
dynablock_t* FindDynablockFromNativeAddress(void* addr); // defined in box86context.h
dynablock_t* FindDynablockDynablocklist(void* addr, kh_dynablocks_t* dynablocks);
uintptr_t StartDynablockList(dynablocklist_t* db);
uintptr_t EndDynablockList(dynablocklist_t* db);
@@ -28,13 +27,9 @@ void MarkDirectDynablock(dynablocklist_t* dynablocks, uintptr_t addr, uintptr_t
// Handling of Dynarec block (i.e. an exectable chunk of x86 translated code)
dynablock_t* DBGetBlock(x86emu_t* emu, uintptr_t addr, int create, dynablock_t** current); // return NULL if block is not found / cannot be created. Don't create if create==0
// source is linked to dest (i.e. source->table[x] = dest->block), so add a "mark" in dest, add a "linked" info to source
void AddMark(dynablock_t* source, dynablock_t* dest, void** table);
// remove a Table mark (and also remove lined info from other dynablock, if any)
void RemoveMark(void** table);
dynablock_t* DBAlternateBlock(x86emu_t* emu, uintptr_t addr, uintptr_t filladdr);
// Create and Add an new dynablock in the list, handling direct/map
dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int with_marks, int* created);
dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* created);
#endif //__DYNABLOCK_H_
+1 -1
View File
@@ -4,6 +4,6 @@
typedef struct dynablock_s dynablock_t;
typedef struct x86emu_s x86emu_t;
void* FillBlock(dynablock_t* block);
void* FillBlock(dynablock_t* block, uintptr_t addr);
#endif //__DYNAREC_ARM_H_
+2
View File
@@ -53,5 +53,7 @@ dynablocklist_t* GetDynablocksFromElf(elfheader_t* h);
void ResetSpecialCaseMainElf(elfheader_t* h);
void CreateMemorymapFile(box86context_t* context, int fd);
int ElfCheckIfUseTCMallocMinimal(elfheader_t* h); // return 1 if tcmalloc is used
#endif //__ELF_LOADER_H_
+78 -6
View File
@@ -126,6 +126,65 @@ typedef struct my_GtkContainerClass_s
void (*_gtk_reserved4) (void);
} my_GtkContainerClass_t;
typedef struct my_GtkActionClass_s
{
my_GObjectClass_t parent_class;
void (* activate) (void* action);
int menu_item_type;
int toolbar_item_type;
void* (* create_menu_item) (void* action);
void* (* create_tool_item) (void* action);
void (* connect_proxy) (void* action, void* proxy);
void (* disconnect_proxy) (void* action, void* proxy);
void* (* create_menu) (void* action);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
} my_GtkActionClass_t;
typedef struct my_GtkMiscClass_s
{
my_GtkWidgetClass_t parent_class;
} my_GtkMiscClass_t;
typedef struct my_GtkLabelClass_s
{
my_GtkMiscClass_t parent_class;
void (* move_cursor) (void* label, int step, int count, int extend_selection);
void (* copy_clipboard) (void* label);
void (* populate_popup) (void* label, void* menu);
int (*activate_link) (void* label, void* uri);
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
} my_GtkLabelClass_t;
typedef struct my_GtkTreeViewClass_s
{
my_GtkContainerClass_t parent_class;
void (* set_scroll_adjustments) (void* tree_view, void* hadjustment, void* vadjustment);
void (* row_activated) (void* tree_view, void* path, void* column);
int (* test_expand_row) (void* tree_view, void* iter, void* path);
int (* test_collapse_row) (void* tree_view, void* iter, void* path);
void (* row_expanded) (void* tree_view, void* iter, void* path);
void (* row_collapsed) (void* tree_view, void* iter, void* path);
void (* columns_changed) (void* tree_view);
void (* cursor_changed) (void* tree_view);
int (* move_cursor) (void* tree_view, int step, int count);
int (* select_all) (void* tree_view);
int (* unselect_all) (void* tree_view);
int (* select_cursor_row) (void* tree_view, int start_editing);
int (* toggle_cursor_row) (void* tree_view);
int (* expand_collapse_cursor_row) (void* tree_view, int logical, int expand, int open_all);
int (* select_cursor_parent) (void* tree_view);
int (* start_interactive_search) (void* tree_view);
void (*_gtk_reserved0) (void);
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
} my_GtkTreeViewClass_t;
// GTypeValueTable
typedef struct my_GTypeValueTable_s {
void (*value_init) (void* value);
@@ -180,13 +239,25 @@ my_GtkTypeInfo_t* findFreeGtkTypeInfo(my_GtkTypeInfo_t* fcts, int parent);
void InitGTKClass(bridge_t *bridge);
void FiniGTKClass();
void SetGObjectID(int id);
void SetGTKObjectID(int id);
void SetGTKWidgetID(int id);
void SetGTKContainerID(int id);
void SetGTypeName(void* f);
#define GTKCLASSES() \
GTKCLASS(GObject) \
GTKCLASS(GtkObject) \
GTKCLASS(GtkWidget) \
GTKCLASS(GtkContainer) \
GTKCLASS(GtkAction) \
GTKCLASS(GtkLabel) \
GTKCLASS(GtkMisc) \
GTKCLASS(GtkTreeView) \
void* wrapCopyGTKClass(void* class, int type);
#define GTKCLASS(A) void Set##A##ID(int id);
GTKCLASSES()
#undef GTKCLASS
void SetGTypeName(void* f);
void AutoBridgeGtk(void*(*ref)(int), void(*unref)(void*));
void* wrapCopyGTKClass(void* cl, int type);
void* unwrapCopyGTKClass(void* klass, int type);
void my_checkGlobalGdkDisplay();
void my_setGlobalGThreadsInit();
@@ -205,6 +276,7 @@ typedef struct my_signal_s {
my_signal_t* new_mysignal(void* f, void* data, void* destroy);
void my_signal_delete(my_signal_t* sig);
int my_signal_is_valid(void* sig);
int my_signal_cb(void* a, void* b, void* c, void* d);
#endif //__GTKCLASS_H__
+2 -2
View File
@@ -132,8 +132,8 @@ typedef struct {
} fpu_ld_t;
typedef struct {
uint64_t ll;
uint64_t ref;
int64_t ll;
int64_t ref;
} fpu_ll_t;
typedef union {
+4 -1
View File
@@ -15,6 +15,9 @@ void CleanStackSize(box86context_t* context);
emu_jmpbuf_t* GetJmpBuf();
void init_pthread_helper();
void fini_pthread_helper();
void fini_pthread_helper(box86context_t* context);
// prepare an "emuthread structure" in pet and return address of function pointer for a "thread creation routine"
void* my_prepare_thread(x86emu_t *emu, void* f, void* arg, int ssize, void** pet);
#endif //_THREADS_H_
+4
View File
@@ -6,4 +6,8 @@ void wine_prereserve(const char* reserve);
extern int wine_preloaded;
void* get_wine_prereserve();
#ifdef DYNAREC
void dynarec_wine_prereserve();
#endif
#endif //__WINE_TOOLS_H__
+4
View File
@@ -29,9 +29,13 @@ void SetFS(x86emu_t *emu, uint16_t v);
uint16_t GetFS(x86emu_t *emu);
uint32_t GetESP(x86emu_t *emu);
void ResetFlags(x86emu_t *emu);
void ResetSegmentsCache(x86emu_t *emu);
const char* DumpCPURegs(x86emu_t* emu, uintptr_t ip);
void StopEmu(x86emu_t* emu, const char* reason);
#ifdef DYNAREC
void DynablockEmuMarker(box86context_t* context);
#endif
void PushExit(x86emu_t* emu);
void* GetExit();
void EmuCall(x86emu_t* emu, uintptr_t addr);
+15 -13
View File
@@ -39,10 +39,13 @@ void FreeLibrarian(lib_t **maplib)
if(!maplib || !*maplib)
return;
if((*maplib)->ownlibs)
if((*maplib)->ownlibs) {
printf_log(LOG_DEBUG, "Closing %d libs from maplib %p\n", (*maplib)->libsz, *maplib);
for (int i=0; i<(*maplib)->libsz; ++i) {
printf_log(LOG_DEBUG, "Unloading %s\n", (*maplib)->libraries[i].lib->name);
Free1Library(&(*maplib)->libraries[i].lib);
}
}
free((*maplib)->libraries);
(*maplib)->libraries = NULL;
@@ -386,21 +389,18 @@ elfheader_t* GetGlobalSymbolElf(lib_t *maplib, const char* name)
uintptr_t start = 0;
uintptr_t end = 0;
if(GetSymbolStartEnd(maplib->mapsymbols, name, &start, &end))
if(start)
return maplib->context->elfs[0];
return maplib->context->elfs[0];
if(GetSymbolStartEnd(maplib->weaksymbols, name, &start, &end))
if(start)
return maplib->context->elfs[0];
return maplib->context->elfs[0];
for(int i=0; i<maplib->libsz; ++i) {
if(GetLibSymbolStartEnd(maplib->libraries[i].lib, name, &start, &end))
if(start) {
int idx = GetElfIndex(maplib->libraries[i].lib);
if(idx==-1) {
printf_log(LOG_NONE, "Warning, getting Elf info for a native symbol \"%s\" from lib \"%s\"\n", name, GetNameLib(maplib->libraries[i].lib));
return NULL;
}
return maplib->context->elfs[idx];
if(GetLibSymbolStartEnd(maplib->libraries[i].lib, name, &start, &end)) {
int idx = GetElfIndex(maplib->libraries[i].lib);
if(idx==-1) {
printf_log(LOG_NONE, "Warning, getting Elf info for a native symbol \"%s\" from lib \"%s\"\n", name, GetNameLib(maplib->libraries[i].lib));
return NULL;
}
return maplib->context->elfs[idx];
}
}
// nope, not found
return NULL;
@@ -557,6 +557,8 @@ void AddOffsetSymbol(lib_t *maplib, void* offs, const char* name)
const char* GetNameOffset(lib_t *maplib, void* offs)
{
if(!maplib || !maplib->mapoffsets)
return NULL;
khint_t k = kh_get(mapoffsets, maplib->mapoffsets, (uintptr_t)offs);
if (k!=kh_end(maplib->mapoffsets))
return kh_value(maplib->mapoffsets, k);
+10 -10
View File
@@ -93,14 +93,14 @@ int EmuLib_Get(library_t* lib, const char* name, uintptr_t *offs, uint32_t *sz)
if(k!=kh_end(lib->priv.n.mapsymbols)) {
*offs = kh_value(lib->priv.n.mapsymbols, k).offs;
*sz = kh_value(lib->priv.n.mapsymbols, k).sz;
return *offs;
return 1;
}
// weak symbols...
k = kh_get(mapsymbols, lib->priv.n.weaksymbols, name);
if(k!=kh_end(lib->priv.n.weaksymbols)) {
*offs = kh_value(lib->priv.n.weaksymbols, k).offs;
*sz = kh_value(lib->priv.n.weaksymbols, k).sz;
return *offs;
return 1;
}
return 0;
}
@@ -111,7 +111,7 @@ int EmuLib_GetNoWeak(library_t* lib, const char* name, uintptr_t *offs, uint32_t
if(k!=kh_end(lib->priv.n.mapsymbols)) {
*offs = kh_value(lib->priv.n.mapsymbols, k).offs;
*sz = kh_value(lib->priv.n.mapsymbols, k).sz;
return *offs;
return 1;
}
return 0;
}
@@ -122,7 +122,7 @@ int EmuLib_GetLocal(library_t* lib, const char* name, uintptr_t *offs, uint32_t
if(k!=kh_end(lib->priv.n.localsymbols)) {
*offs = kh_value(lib->priv.n.localsymbols, k).offs;
*sz = kh_value(lib->priv.n.localsymbols, k).sz;
return *offs;
return 1;
}
return 0;
}
@@ -201,7 +201,6 @@ static int loadEmulatedLib(const char* libname, library_t *lib, box86context_t*
ElfAttachLib(elf_header, lib);
lib->type = 1;
lib->context = context;
lib->fini = EmuLib_Fini;
lib->get = EmuLib_Get;
lib->getnoweak = EmuLib_GetNoWeak;
@@ -242,6 +241,7 @@ library_t *NewLibrary(const char* path, box86context_t* context)
lib->path = strdup(path);
lib->name = Path2Name(path);
lib->nbdot = NbDot(lib->name);
lib->context = context;
lib->type = -1;
printf_log(LOG_DEBUG, "Simplified name is \"%s\"\n", lib->name);
if(box86_nopulse) {
@@ -581,7 +581,7 @@ int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr
printf_log(LOG_NONE, "Warning, function %s not found\n", buff);
} else
AddOffsetSymbol(lib->context->maplib, symbol, name);
*addr = AddBridge(lib->priv.w.bridge, kh_value(lib->mysymbolmap, k), symbol, 0);
*addr = AddBridge(lib->priv.w.bridge, lib->context, kh_value(lib->mysymbolmap, k), symbol, 0);
*size = sizeof(void*);
return 1;
}
@@ -599,7 +599,7 @@ int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr
printf_log(LOG_NONE, "Warning, function %s not found\n", buff);
} else
AddOffsetSymbol(lib->context->maplib, symbol, name);
*addr = AddBridge(lib->priv.w.bridge, kh_value(lib->stsymbolmap, k), symbol, 4); // all of this for this little "4"
*addr = AddBridge(lib->priv.w.bridge, lib->context, kh_value(lib->stsymbolmap, k), symbol, 4); // all of this for this little "4"
*size = sizeof(void*);
return 1;
}
@@ -618,7 +618,7 @@ int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr
return 0;
} else
AddOffsetSymbol(lib->context->maplib, symbol, name);
*addr = AddBridge(lib->priv.w.bridge, kh_value(lib->symbolmap, k), symbol, 0);
*addr = AddBridge(lib->priv.w.bridge, lib->context, kh_value(lib->symbolmap, k), symbol, 0);
*size = sizeof(void*);
return 1;
}
@@ -637,7 +637,7 @@ int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr
return 0;
} else
AddOffsetSymbol(lib->context->maplib, symbol, name);
*addr = AddBridge(lib->priv.w.bridge, kh_value(lib->wsymbolmap, k), symbol, 0);
*addr = AddBridge(lib->priv.w.bridge, lib->context, kh_value(lib->wsymbolmap, k), symbol, 0);
*size = sizeof(void*);
return 1;
}
@@ -655,7 +655,7 @@ int getSymbolInMaps(library_t*lib, const char* name, int noweak, uintptr_t *addr
return 0;
} else
AddOffsetSymbol(lib->context->maplib, symbol, name);
*addr = AddBridge(lib->priv.w.bridge, kh_value(lib->symbol2map, k).w, symbol, 0);
*addr = AddBridge(lib->priv.w.bridge, lib->context, kh_value(lib->symbol2map, k).w, symbol, 0);
*size = sizeof(void*);
return 1;
}
+13
View File
@@ -18,6 +18,7 @@ GO("libSDL2.so", sdl2)
GO("libsdl2-2.0.so.0", sdl2)
GO("libSDL2_mixer-2.0.so.0", sdl2mixer)
GO("libSDL2_image-2.0.so.0", sdl2image)
GO("libSDL2_ttf-2.0.so.0", sdl2ttf)
GO("libSDL-1.2.so.0", sdl1)
GO("libSDL-1.1.so.0", sdl1)
GO("libSDL_mixer-1.2.so.0", sdl1mixer)
@@ -67,6 +68,7 @@ GO("openal.so", openal)
GO("libalut.so.0", alut)
GO("libjpeg.so.8", libjpeg)
GO("libjpeg.so.62", libjpeg62)
GO("libturbojpeg.so.0", turbojpeg)
GO("libcurl.so.4", curl)
GO("libcurl-gnutls.so.4", curl)
GO("libudev.so.0", udev0)
@@ -84,6 +86,8 @@ GO("libpulse.so.0", pulse)
GO("libsndfile.so.1", libsndfile)
GO("libgtk-x11-2.0.so.0", gtkx112)
GO("libgdk-x11-2.0.so.0", gdkx112)
GO("libgtk-3.so.0", gtk3)
GO("libgdk-3.so.0", gdk3)
GO("libgdk_pixbuf-2.0.so.0", gdkpixbuf2)
GO("libgio-2.0.so.0", gio2)
GO("libgmodule-2.0.so.0", gmodule2)
@@ -123,5 +127,14 @@ GO("libmpg123.so.0", mpg123)
GO("libgnutls.so.30", gnutls)
GO("libcups.so.2", libcups)
GO("d3dadapter9.so.1", d3dadapter9)
GO("libvulkan.so.1", vulkan)
GO("libvulkan.so", vulkan)
GO("libwayland-client.so.0", waylandclient)
GO("libxml2.so.2", xml2)
GO("libxslt.so.1", xslt)
GO("libldap_r-2.4.so.2", ldapr)
GO("liblber-2.4.so.2", lber)
GO("libnsl.so.1", nsl)
GO("liblcms2.so.2", lcms2)
GO("ld-linux.so.2", ldlinux)
+6 -2
View File
@@ -65,7 +65,9 @@ void myStackAlign(const char* fmt, uint32_t* st, uint32_t* mystack)
case '7':
case '8':
case '9':
case '.': ++p; break; // formating, ignored
case '.':
case '+':
case '-': ++p; break; // formating, ignored
case 'm': state = 0; ++p; break; // no argument
case 'n':
case 'p':
@@ -356,7 +358,9 @@ void myStackAlignW(const char* fmt, uint32_t* st, uint32_t* mystack)
case '7':
case '8':
case '9':
case '.': ++p; break; // formating, ignored
case '.':
case '+':
case '-': ++p; break; // formating, ignored
case 'm': state = 0; ++p; break; // no argument
case 'n':
case 'p':
+3 -3
View File
@@ -70,7 +70,7 @@ static void* reverse_chunkfunFct(library_t* lib, void* fct)
#define GO(A) if(my_chunkfun_##A == fct) return (void*)my_chunkfun_fct_##A;
SUPER()
#undef GO
return (void*)AddBridge(lib->priv.w.bridge, pFL, fct, 0);
return (void*)AddBridge(lib->priv.w.bridge, lib->context, pFL, fct, 0);
}
// freefun
#define GO(A) \
@@ -103,7 +103,7 @@ static void* reverse_freefunFct(library_t* lib, void* fct)
#define GO(A) if(my_freefun_##A == fct) return (void*)my_freefun_fct_##A;
SUPER()
#undef GO
return (void*)AddBridge(lib->priv.w.bridge, vFp, fct, 0);
return (void*)AddBridge(lib->priv.w.bridge, lib->context, vFp, fct, 0);
}
#undef SUPER
@@ -217,7 +217,7 @@ void obstackSetup()
// save the real function
real_obstack_alloc_failed_handler = obstack_alloc_failed_handler;
// bridge the real function for x86 world
my_obstack_alloc_failed_handler = (void*)AddCheckBridge(my_context->system, vFv, real_obstack_alloc_failed_handler, 0);
my_obstack_alloc_failed_handler = (void*)AddCheckBridge(my_context->system, my_context, vFv, real_obstack_alloc_failed_handler, 0);
ref_obstack_alloc_failed_handler = my_obstack_alloc_failed_handler;
// setup our version of the function
obstack_alloc_failed_handler = actual_obstack_alloc_failed_handler;
+1 -2
View File
@@ -107,8 +107,7 @@ SDL1_RWops_t* AddNativeRW(x86emu_t* emu, SDL1_RWops_t* ops)
// get or create wrapper, add it to map and change to the emulated one if rw
#define GO(A, W) \
fnc = CheckBridged(system, my_native_##A); \
if(!fnc) fnc = AddBridge(system, W, my_native_##A, 0); \
fnc = AddCheckBridge(system, my_context, W, my_native_##A, 0); \
newrw->A = (sdl1_##A)fnc;
GO(seek, iFpii)
+10 -45
View File
@@ -49,7 +49,6 @@ typedef struct SDL2_RWops_s {
struct {
SDL2_RWops_t *orig;
sdl2_freerw custom_free;
x86emu_t *emu;
} my;
} hidden;
} SDL2_RWops_t;
@@ -78,58 +77,27 @@ EXPORT int32_t my2_native_close(SDL2_RWops_t *context)
}
EXPORT int64_t my2_emulated_size(SDL2_RWops_t *context)
{
x86emu_t *emu = context->hidden.my.emu;
SetCallbackNArg(emu, 1);
SetCallbackArg(emu, 0, context->hidden.my.orig);
SetCallbackAddress(emu, (uintptr_t)context->hidden.my.orig->size);
RunCallback(emu);
return (int64_t)GetEDXEAX(emu);
return (int64_t)RunFunction64(my_context, (uintptr_t)context->hidden.my.orig->size, 1, context->hidden.my.orig);
}
EXPORT int64_t my2_emulated_seek(SDL2_RWops_t *context, int64_t offset, int32_t whence)
{
x86emu_t *emu = context->hidden.my.emu;
SetCallbackNArg(emu, 4);
SetCallbackArg(emu, 0, context->hidden.my.orig);
SetCallbackArg(emu, 1, (void*)(uintptr_t)(offset&0xffffffff));
SetCallbackArg(emu, 2, (void*)(uintptr_t)((offset>>32)&0xffffffff));
SetCallbackArg(emu, 3, (void*)whence);
SetCallbackAddress(emu, (uintptr_t)context->hidden.my.orig->seek);
RunCallback(emu);
return (int64_t)GetEDXEAX(emu);
return (int64_t)RunFunction64(my_context,
(uintptr_t)context->hidden.my.orig->seek, 4, context->hidden.my.orig,
(void*)(uintptr_t)(offset&0xffffffff),
(void*)(uintptr_t)((offset>>32)&0xffffffff),
whence);
}
EXPORT int32_t my2_emulated_read(SDL2_RWops_t *context, void *ptr, int32_t size, int32_t maxnum)
{
x86emu_t *emu = context->hidden.my.emu;
SetCallbackNArg(emu, 4);
SetCallbackArg(emu, 0, context->hidden.my.orig);
SetCallbackArg(emu, 1, ptr);
SetCallbackArg(emu, 2, (void*)size);
SetCallbackArg(emu, 3, (void*)maxnum);
SetCallbackAddress(emu, (uintptr_t)context->hidden.my.orig->read);
RunCallback(emu);
return (int32_t)GetEAX(emu);
return (int32_t)RunFunction(my_context, (uintptr_t)context->hidden.my.orig->read, 4, context->hidden.my.orig, ptr, size, maxnum);
}
EXPORT int32_t my2_emulated_write(SDL2_RWops_t *context, const void *ptr, int32_t size, int32_t num)
{
x86emu_t *emu = context->hidden.my.emu;
SetCallbackNArg(emu, 4);
SetCallbackArg(emu, 0, context->hidden.my.orig);
SetCallbackArg(emu, 1, (void*)ptr);
SetCallbackArg(emu, 2, (void*)size);
SetCallbackArg(emu, 3, (void*)num);
SetCallbackAddress(emu, (uintptr_t)context->hidden.my.orig->write);
RunCallback(emu);
return (int32_t)GetEAX(emu);
return (int32_t)RunFunction(my_context, (uintptr_t)context->hidden.my.orig->write, 4, context->hidden.my.orig, ptr, size, num);
}
EXPORT int32_t my2_emulated_close(SDL2_RWops_t *context)
{
x86emu_t *emu = context->hidden.my.emu;
SetCallbackNArg(emu, 1);
SetCallbackArg(emu, 0, context->hidden.my.orig);
SetCallbackAddress(emu, (uintptr_t)context->hidden.my.orig->close);
int32_t ret = RunCallback(emu);
FreeCallback(emu);
return ret;
return (int32_t)RunFunction(my_context, (uintptr_t)context->hidden.my.orig->close, 1, context->hidden.my.orig);
}
SDL2_RWops_t* AddNativeRW2(x86emu_t* emu, SDL2_RWops_t* ops)
@@ -149,8 +117,7 @@ SDL2_RWops_t* AddNativeRW2(x86emu_t* emu, SDL2_RWops_t* ops)
// get or create wrapper, add it to map and change to the emulated one if rw
#define GO(A, W) \
fnc = CheckBridged(system, my2_native_##A); \
if(!fnc) fnc = AddBridge(system, W, my2_native_##A, 0); \
fnc = AddCheckBridge(system, my_context, W, my2_native_##A, 0); \
newrw->A = (sdl2_##A)fnc;
GO(size, IFp)
@@ -178,7 +145,6 @@ SDL2_RWops_t* RWNativeStart2(x86emu_t* emu, SDL2_RWops_t* ops)
SDL2_RWops_t* newrw = Alloc();
newrw->type = BOX86RW;
newrw->hidden.my.orig = ops;
newrw->hidden.my.emu = AddSmallCallback(emu, 0, 0, NULL, NULL, NULL, NULL);
// create wrapper
#define GO(A, W) \
@@ -203,7 +169,6 @@ void RWNativeEnd2(SDL2_RWops_t* ops)
if(ops->type != BOX86RW)
return; // do nothing
FreeCallback(ops->hidden.my.emu);
ops->hidden.my.custom_free(ops);
}
+157 -75
View File
@@ -202,6 +202,15 @@ typedef struct i386_ucontext_s
struct i386_xstate xstate;
} i386_ucontext_t;
typedef struct i386_sigframe_s {
uintptr_t pretcode; // pointer to retcode
int sig;
i386_mcontext_t cpustate;
struct i386_xstate fpstate;
uintptr_t extramask[64-1];
char retcode[8];
} i386_sigframe_t;
struct kernel_sigaction {
void (*k_sa_handler) (int);
unsigned long sa_flags;
@@ -260,11 +269,11 @@ uint32_t RunFunctionHandler(int* exit, uintptr_t fnc, int nargs, ...)
// trace_start = 0; trace_end = 1; // disabling trace, globably for now...
x86emu_t *emu = get_signal_emu();
printf_log(LOG_DEBUG, "signal function handler %p called, ESP=%p\n", (void*)fnc, (void*)R_ESP);
printf_log(LOG_DEBUG, "%04d|signal function handler %p called, ESP=%p\n", GetTID(), (void*)fnc, (void*)R_ESP);
SetFS(emu, default_fs);
/*SetFS(emu, default_fs);*/
for (int i=0; i<6; ++i)
emu->segs_clean[i] = 0;
emu->segs_serial[i] = 0;
R_ESP -= nargs*4; // need to push in reverse order
@@ -312,12 +321,11 @@ EXPORT int my_sigaltstack(x86emu_t* emu, const i386_stack_t* ss, i386_stack_t* o
}
return 0;
}
printf_log(LOG_DEBUG, "sigaltstack called ss=%p[flags=0x%x, sp=%p, ss=0x%x], oss=%p\n", ss, ss->ss_flags, ss->ss_sp, ss->ss_size, oss);
printf_log(LOG_DEBUG, "%04d|sigaltstack called ss=%p[flags=0x%x, sp=%p, ss=0x%x], oss=%p\n", GetTID(), ss, ss->ss_flags, ss->ss_sp, ss->ss_size, oss);
if(ss->ss_flags && ss->ss_flags!=SS_DISABLE && ss->ss_flags!=SS_ONSTACK) {
errno = EINVAL;
return -1;
}
//TODO: SS_ONSTACK is not correctly handled, has the stack is NOT the one where the signal came from
if(ss->ss_flags==SS_DISABLE) {
if(new_ss)
@@ -365,67 +373,116 @@ void my_sighandler(int32_t sig)
RunFunctionHandler(&exits, restorer, 0);
}
#ifdef DYNAREC
uintptr_t getX86Address(dynablock_t* db, uintptr_t arm_addr)
{
uintptr_t x86addr = (uintptr_t)db->x86_addr;
uintptr_t armaddr = (uintptr_t)db->block;
int i = 0;
do {
int x86sz = 0;
int armsz = 0;
do {
x86sz+=db->instsize[i].x86;
armsz+=db->instsize[i].nat*4;
}
while(!db->instsize[++i].x86);
if(arm_addr>=armaddr && arm_addr<(armaddr+armsz))
return x86addr;
armaddr+=armsz;
x86addr+=x86sz;
if(arm_addr==armaddr)
return x86addr;
} while(db->instsize[i].x86 || db->instsize[i].nat);
return x86addr;
}
#endif
void my_sigactionhandler_oldpc(int32_t sig, siginfo_t* info, void * ucntx, void** old_pc)
{
// need to creat some x86_ucontext????
// need to create some x86_ucontext????
pthread_mutex_unlock(&my_context->mutex_trace); // just in case
printf_log(LOG_DEBUG, "Sigactionhanlder for signal #%d called (jump to %p)\n", sig, (void*)my_context->signals[sig]);
printf_log(LOG_DEBUG, "Sigactionhanlder for signal #%d called (jump to %p/%s)\n", sig, (void*)my_context->signals[sig], GetNativeName((void*)my_context->signals[sig]));
uintptr_t restorer = my_context->restorer[sig];
// try to fill some sigcontext....
i386_ucontext_t sigcontext = {0};
x86emu_t *emu = thread_get_emu(); // not good, emu is probably not up to date, especially using dynarec
// stack traking
x86emu_t *sigemu = get_signal_emu();
i386_stack_t *new_ss = (i386_stack_t*)pthread_getspecific(sigstack_key);
if(!new_ss) {
sigcontext.uc_stack.ss_sp = sigemu->init_stack;
sigcontext.uc_stack.ss_size = sigemu->size_stack;
} else {
sigcontext.uc_stack.ss_sp = new_ss->ss_sp;
sigcontext.uc_stack.ss_size = new_ss->ss_size;
}
// get general register
sigcontext.uc_mcontext.gregs[REG_EAX] = R_EAX;
sigcontext.uc_mcontext.gregs[REG_ECX] = R_ECX;
sigcontext.uc_mcontext.gregs[REG_EDX] = R_EDX;
sigcontext.uc_mcontext.gregs[REG_EDI] = R_EDI;
sigcontext.uc_mcontext.gregs[REG_ESI] = R_ESI;
sigcontext.uc_mcontext.gregs[REG_EBP] = R_EBP;
sigcontext.uc_mcontext.gregs[REG_EIP] = R_EIP;
sigcontext.uc_mcontext.gregs[REG_ESP] = R_ESP+4;
sigcontext.uc_mcontext.gregs[REG_EBX] = R_EBX;
// flags
sigcontext.uc_mcontext.gregs[REG_EFL] = emu->packed_eflags.x32;
// get segments
sigcontext.uc_mcontext.gregs[REG_GS] = R_GS;
sigcontext.uc_mcontext.gregs[REG_FS] = R_FS;
sigcontext.uc_mcontext.gregs[REG_ES] = R_ES;
sigcontext.uc_mcontext.gregs[REG_DS] = R_DS;
sigcontext.uc_mcontext.gregs[REG_CS] = R_CS;
sigcontext.uc_mcontext.gregs[REG_SS] = R_SS;
// get FloatPoint status
sigcontext.uc_mcontext.fpregs = (i386_fpregset_t)&sigcontext.xstate;
fpu_fxsave(emu, &sigcontext.xstate);
// add custom SIGN in reserved area
//((unsigned int *)(&sigcontext.xstate.fpstate.padding))[8*4+12] = 0x46505853; // not yet, when XSAVE / XRSTR will be ready
// get signal mask
// get actual register in case the signal was from inside a dynablock
// get that actual ESP first!
x86emu_t *emu = thread_get_emu();
uint32_t *frame = (uint32_t*)R_ESP;
#if defined(DYNAREC) && defined(__arm__)
ucontext_t *p = (ucontext_t *)ucntx;
void * pc = (void*)p->uc_mcontext.arm_pc;
dynablock_t* db = FindDynablockFromNativeAddress(pc);
if(db) {
sigcontext.uc_mcontext.gregs[REG_EAX] = p->uc_mcontext.arm_r4;
sigcontext.uc_mcontext.gregs[REG_ECX] = p->uc_mcontext.arm_r5;
sigcontext.uc_mcontext.gregs[REG_EDX] = p->uc_mcontext.arm_r6;
sigcontext.uc_mcontext.gregs[REG_EBX] = p->uc_mcontext.arm_r7;
sigcontext.uc_mcontext.gregs[REG_ESP] = p->uc_mcontext.arm_r8+4;
sigcontext.uc_mcontext.gregs[REG_EBP] = p->uc_mcontext.arm_r9;
sigcontext.uc_mcontext.gregs[REG_ESI] = p->uc_mcontext.arm_r10;
sigcontext.uc_mcontext.gregs[REG_EDI] = p->uc_mcontext.arm_fp;
sigcontext.uc_mcontext.gregs[REG_EIP] = (uint32_t)db->x86_addr; // this is partly wrong...
frame = (uint32_t*)p->uc_mcontext.arm_r8;
}
#endif
// stack tracking
x86emu_t *sigemu = get_signal_emu();
i386_stack_t *new_ss = my_context->onstack[sig]?(i386_stack_t*)pthread_getspecific(sigstack_key):NULL;
int used_stack = 0;
if(new_ss) {
if(new_ss->ss_flags == SS_ONSTACK) { // already using it!
frame = (uint32_t*)sigemu->regs[_SP].dword[0];
} else {
frame = (uint32_t*)(((uintptr_t)new_ss->ss_sp + new_ss->ss_size - 16) & ~7);
used_stack = 1;
new_ss->ss_flags = SS_ONSTACK;
}
}
// TODO: do I need to really setup 2 stack frame? That doesn't seems right!
// setup stack frame
// try to fill some sigcontext....
frame -= sizeof(i386_ucontext_t)/4;
i386_ucontext_t *sigcontext = (i386_ucontext_t*)frame;
// get general register
sigcontext->uc_mcontext.gregs[REG_EAX] = R_EAX;
sigcontext->uc_mcontext.gregs[REG_ECX] = R_ECX;
sigcontext->uc_mcontext.gregs[REG_EDX] = R_EDX;
sigcontext->uc_mcontext.gregs[REG_EDI] = R_EDI;
sigcontext->uc_mcontext.gregs[REG_ESI] = R_ESI;
sigcontext->uc_mcontext.gregs[REG_EBP] = R_EBP;
sigcontext->uc_mcontext.gregs[REG_EIP] = R_EIP;
sigcontext->uc_mcontext.gregs[REG_ESP] = R_ESP;
sigcontext->uc_mcontext.gregs[REG_EBX] = R_EBX;
// flags
sigcontext->uc_mcontext.gregs[REG_EFL] = emu->packed_eflags.x32;
// get segments
sigcontext->uc_mcontext.gregs[REG_GS] = R_GS;
sigcontext->uc_mcontext.gregs[REG_FS] = R_FS;
sigcontext->uc_mcontext.gregs[REG_ES] = R_ES;
sigcontext->uc_mcontext.gregs[REG_DS] = R_DS;
sigcontext->uc_mcontext.gregs[REG_CS] = R_CS;
sigcontext->uc_mcontext.gregs[REG_SS] = R_SS;
#if defined(DYNAREC) && defined(__arm__)
if(db) {
sigcontext->uc_mcontext.gregs[REG_EAX] = p->uc_mcontext.arm_r4;
sigcontext->uc_mcontext.gregs[REG_ECX] = p->uc_mcontext.arm_r5;
sigcontext->uc_mcontext.gregs[REG_EDX] = p->uc_mcontext.arm_r6;
sigcontext->uc_mcontext.gregs[REG_EBX] = p->uc_mcontext.arm_r7;
sigcontext->uc_mcontext.gregs[REG_ESP] = p->uc_mcontext.arm_r8;
sigcontext->uc_mcontext.gregs[REG_EBP] = p->uc_mcontext.arm_r9;
sigcontext->uc_mcontext.gregs[REG_ESI] = p->uc_mcontext.arm_r10;
sigcontext->uc_mcontext.gregs[REG_EDI] = p->uc_mcontext.arm_fp;
sigcontext->uc_mcontext.gregs[REG_EIP] = getX86Address(db, (uintptr_t)pc);
}
#endif
// get FloatPoint status
sigcontext->uc_mcontext.fpregs = (i386_fpregset_t)&sigcontext->xstate;
fpu_fxsave(emu, &sigcontext->xstate);
// add custom SIGN in reserved area
//((unsigned int *)(&sigcontext.xstate.fpstate.padding))[8*4+12] = 0x46505853; // not yet, when XSAVE / XRSTR will be ready
// get signal mask
if(!new_ss) {
sigcontext->uc_stack.ss_sp = sigemu->init_stack;
sigcontext->uc_stack.ss_size = sigemu->size_stack;
sigcontext->uc_stack.ss_flags = SS_DISABLE;
} else {
sigcontext->uc_stack.ss_sp = new_ss->ss_sp;
sigcontext->uc_stack.ss_size = new_ss->ss_size;
sigcontext->uc_stack.ss_flags = new_ss->ss_flags;
}
// Try to guess some REG_TRAPNO
/*
TRAP_x86_DIVIDE = 0, // Division by zero exception
@@ -448,27 +505,33 @@ void my_sigactionhandler_oldpc(int32_t sig, siginfo_t* info, void * ucntx, void*
TRAP_x86_MCHK = 18, // Machine check exception
TRAP_x86_CACHEFLT = 19 // SIMD exception (via SIGFPE) if CPU is SSE capable otherwise Cache flush exception (via SIGSEV)
*/
intptr_t esp = (intptr_t)sigcontext.uc_mcontext.gregs[REG_ESP];
if(sig==SIGBUS)
sigcontext.uc_mcontext.gregs[REG_TRAPNO] = 17;
sigcontext->uc_mcontext.gregs[REG_TRAPNO] = 17;
else if(sig==SIGSEGV) {
sigcontext.uc_mcontext.gregs[REG_TRAPNO] = (info->si_code == SEGV_ACCERR)?((abs((intptr_t)info->si_addr-esp)<16)?12:14):13; // how to differenciate between a STACKFLT and a PAGEFAULT?
sigcontext->uc_mcontext.gregs[REG_TRAPNO] =
(info->si_code == SEGV_ACCERR)?((abs((intptr_t)info->si_addr-(intptr_t)sigcontext->uc_mcontext.gregs[REG_ESP])<16)?12:13):14; // how to differenciate between a STACKFLT and a PAGEFAULT?
} else if(sig==SIGFPE)
sigcontext.uc_mcontext.gregs[REG_TRAPNO] = 19;
sigcontext->uc_mcontext.gregs[REG_TRAPNO] = 19;
else if(sig==SIGILL)
sigcontext.uc_mcontext.gregs[REG_TRAPNO] = 6;
sigcontext->uc_mcontext.gregs[REG_TRAPNO] = 6;
// call the signal handler
i386_ucontext_t sigcontext_copy = sigcontext;
i386_ucontext_t sigcontext_copy = *sigcontext;
// set stack pointer
sigemu->regs[_SP].dword[0] = (uintptr_t)frame;
// set segments
memcpy(sigemu->segs, emu->segs, sizeof(sigemu->segs));
int exits = 0;
int ret = RunFunctionHandler(&exits, my_context->signals[sig], 3, sig, info, &sigcontext);
int ret = RunFunctionHandler(&exits, my_context->signals[sig], 3, sig, info, sigcontext);
if(memcmp(&sigcontext, &sigcontext_copy, sizeof(sigcontext))) {
if(memcmp(sigcontext, &sigcontext_copy, sizeof(i386_ucontext_t))) {
emu_jmpbuf_t* ejb = GetJmpBuf();
if(ejb->jmpbuf_ok) {
#define GO(R) if(sigcontext.uc_mcontext.gregs[REG_E##R]!=sigcontext_copy.uc_mcontext.gregs[REG_E##R]) ejb->emu->regs[_##R].dword[0]=sigcontext.uc_mcontext.gregs[REG_E##R]
#define GO(R) if(sigcontext->uc_mcontext.gregs[REG_E##R]!=sigcontext_copy.uc_mcontext.gregs[REG_E##R]) ejb->emu->regs[_##R].dword[0]=sigcontext->uc_mcontext.gregs[REG_E##R]
GO(AX);
GO(CX);
GO(DX);
@@ -478,12 +541,12 @@ void my_sigactionhandler_oldpc(int32_t sig, siginfo_t* info, void * ucntx, void*
GO(SP);
GO(BX);
#undef GO
if(sigcontext.uc_mcontext.gregs[REG_EIP]!=sigcontext_copy.uc_mcontext.gregs[REG_EIP]) ejb->emu->ip.dword[0]=sigcontext.uc_mcontext.gregs[REG_EIP];
sigcontext.uc_mcontext.gregs[REG_EIP] = R_EIP;
if(sigcontext->uc_mcontext.gregs[REG_EIP]!=sigcontext_copy.uc_mcontext.gregs[REG_EIP]) ejb->emu->ip.dword[0]=sigcontext->uc_mcontext.gregs[REG_EIP];
sigcontext->uc_mcontext.gregs[REG_EIP] = R_EIP;
// flags
if(sigcontext.uc_mcontext.gregs[REG_EFL]!=sigcontext_copy.uc_mcontext.gregs[REG_EFL]) ejb->emu->packed_eflags.x32=sigcontext.uc_mcontext.gregs[REG_EFL];
if(sigcontext->uc_mcontext.gregs[REG_EFL]!=sigcontext_copy.uc_mcontext.gregs[REG_EFL]) ejb->emu->packed_eflags.x32=sigcontext->uc_mcontext.gregs[REG_EFL];
// get segments
#define GO(S) if(sigcontext.uc_mcontext.gregs[REG_##S]!=sigcontext_copy.uc_mcontext.gregs[REG_##S]) {ejb->emu->segs[_##S]=sigcontext.uc_mcontext.gregs[REG_##S]; ejb->emu->segs_clean[_##S] = 0;}
#define GO(S) if(sigcontext->uc_mcontext.gregs[REG_##S]!=sigcontext_copy.uc_mcontext.gregs[REG_##S]) {ejb->emu->segs[_##S]=sigcontext->uc_mcontext.gregs[REG_##S]; ejb->emu->segs_serial[_##S] = 0;}
GO(GS);
GO(FS);
GO(ES);
@@ -494,16 +557,29 @@ void my_sigactionhandler_oldpc(int32_t sig, siginfo_t* info, void * ucntx, void*
printf_log(LOG_DEBUG, "Context has been changed in Sigactionhanlder, doing longjmp to resume emu\n");
if(old_pc)
*old_pc = NULL; // re-init the value to allow another segfault at the same place
if(used_stack) // release stack
new_ss->ss_flags = 0;
longjmp(ejb->jmpbuf, 1);
}
printf_log(LOG_INFO, "Warning, context has been changed in Sigactionhanlder%s\n", (sigcontext.uc_mcontext.gregs[REG_EIP]!=sigcontext_copy.uc_mcontext.gregs[REG_EIP])?" (EIP changed)":"");
printf_log(LOG_INFO, "Warning, context has been changed in Sigactionhanlder%s\n", (sigcontext->uc_mcontext.gregs[REG_EIP]!=sigcontext_copy.uc_mcontext.gregs[REG_EIP])?" (EIP changed)":"");
}
printf_log(LOG_DEBUG, "Sigactionhanlder main function returned (exit=%d, restorer=%p)\n", exits, (void*)restorer);
if(exits)
exit(ret);
if(restorer)
RunFunctionHandler(&exits, restorer, 0);
if(used_stack) // release stack
new_ss->ss_flags = 0;
}
#ifdef DYNAREC
static int hasDBFromAddress(uintptr_t addr)
{
int idx = (addr>>DYNAMAP_SHIFT);
return my_context->dynmap[idx]?1:0;
}
#endif
void my_box86signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
{
// sig==SIGSEGV || sig==SIGBUS || sig==SIGILL here!
@@ -519,7 +595,7 @@ void my_box86signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
#warning Unhandled architecture
#endif
#ifdef DYNAREC
if(sig==SIGSEGV && addr && info->si_code == SEGV_ACCERR && getDBFromAddress((uintptr_t)addr)) {
if(sig==SIGSEGV && addr && info->si_code == SEGV_ACCERR && hasDBFromAddress((uintptr_t)addr)) {
if(box86_dynarec_smc) {
dynablock_t* db_pc = NULL;
dynablock_t* db_addr = NULL;
@@ -531,6 +607,9 @@ void my_box86signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
dynarec_log(LOG_NONE, "Warning: Access to protected %p from %p, inside same dynablock\n", addr, pc);
}
}
if(db_addr && !db_addr->nolinker) {
dynarec_log(LOG_NONE, "Warning: Access to protected %p from %p, inside a dynablock with linker\n", addr, pc);
}
}
dynarec_log(LOG_DEBUG, "Access to protected %p from %p, unprotecting memory\n", addr, pc);
// access error
@@ -559,13 +638,15 @@ void my_box86signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
x86emu_t* emu = thread_get_emu();
x86pc = R_EIP;
esp = (void*)R_ESP;
#if defined(__arm__) && defined(DYNAREC)
#if defined(__arm__) && defined(DYNAREC)
if(db && p->uc_mcontext.arm_r0>0x10000) {
emu = (x86emu_t*)p->uc_mcontext.arm_r0;
x86pc = (uintptr_t)db->x86_addr; // sadly, r12 is probably not actual eip, so use db info for now
}
if(db) {
x86pc = getX86Address(db, (uintptr_t)pc);
esp = (void*)p->uc_mcontext.arm_r8;
}
#endif
#endif
x86name = getAddrFunctionName(x86pc);
elfheader_t* elf = FindElfAddress(my_context, x86pc);
if(elf)
@@ -654,7 +735,6 @@ int EXPORT my_sigaction(x86emu_t* emu, int signum, const x86_sigaction_t *act, x
if(signum==SIGILL && emu->context->no_sigill)
return 0;
struct sigaction newact = {0};
struct sigaction old = {0};
if(act) {
@@ -676,6 +756,7 @@ int EXPORT my_sigaction(x86emu_t* emu, int signum, const x86_sigaction_t *act, x
newact.sa_handler = act->_u._sa_handler;
}
my_context->restorer[signum] = (act->sa_flags&0x04000000)?(uintptr_t)act->sa_restorer:0;
my_context->onstack[signum] = (act->sa_flags&SA_ONSTACK)?1:0;
}
int ret = 0;
if(signum!=SIGSEGV && signum!=SIGBUS && signum!=SIGILL)
@@ -915,8 +996,9 @@ EXPORT int my_swapcontext(x86emu_t* emu, void* ucp1, void* ucp2)
void init_signal_helper(box86context_t* context)
{
// setup signal handling
for(int i=0; i<MAX_SIGNAL; ++i)
for(int i=0; i<MAX_SIGNAL; ++i) {
context->signals[i] = 1; // SIG_DFL
}
struct sigaction action;
action.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER;
action.sa_sigaction = my_box86signalhandler;
+51 -12
View File
@@ -133,15 +133,17 @@ static void FreeCancelThread(box86context_t* context)
kh_foreach_value(context->cancelthread, buff, free(buff))
kh_destroy(cancelthread, context->cancelthread);
pthread_mutex_unlock(&context->mutex_thread);
my_context->cancelthread = NULL;
context->cancelthread = NULL;
}
static __pthread_unwind_buf_t* AddCancelThread(uintptr_t buff)
{
int ret;
pthread_mutex_lock(&my_context->mutex_thread);
khint_t k = kh_put(cancelthread, my_context->cancelthread, buff, &ret);
if(ret)
kh_value(my_context->cancelthread, k) = (__pthread_unwind_buf_t*)calloc(1, sizeof(__pthread_unwind_buf_t));
__pthread_unwind_buf_t* r = kh_value(my_context->cancelthread, k);
pthread_mutex_unlock(&my_context->mutex_thread);
return r;
}
@@ -212,11 +214,29 @@ static void* pthread_routine(void* p)
{
// create the key
pthread_once(&thread_key_once, thread_key_alloc);
// free current emuthread if it exist
{
void* t = pthread_getspecific(thread_key);
if(t) {
// not sure how this could happens
printf_log(LOG_INFO, "Clean of an existing ET for Thread %04d\n", GetTID());
emuthread_destroy(t);
}
}
pthread_setspecific(thread_key, p);
// call the function
emuthread_t *et = (emuthread_t*)p;
et->emu->type = EMUTYPE_MAIN;
void* ret = (void*)RunFunctionWithEmu(et->emu, 0, et->fnc, 1, et->arg);
// setup callstack and run...
x86emu_t* emu = et->emu;
R_ESP -= 4;
uint32_t *sp = (uint32_t*)R_ESP;
*sp = (uintptr_t)et->arg;
PushExit(emu);
R_EIP = et->fnc;
DynaRun(et->emu);
void* ret = (void*)R_EAX;
//void* ret = (void*)RunFunctionWithEmu(et->emu, 0, et->fnc, 1, et->arg);
return ret;
}
@@ -286,6 +306,26 @@ EXPORT int my_pthread_create(x86emu_t *emu, void* t, void* attr, void* start_rou
pthread_routine, et);
}
void* my_prepare_thread(x86emu_t *emu, void* f, void* arg, int ssize, void** pet)
{
int stacksize = (ssize)?ssize:(2*1024*1024); //default stack size is 2Mo
void* stack = malloc(stacksize);
emuthread_t *et = (emuthread_t*)calloc(1, sizeof(emuthread_t));
x86emu_t *emuthread = NewX86Emu(emu->context, (uintptr_t)f, (uintptr_t)stack, stacksize, 1);
SetupX86Emu(emuthread);
SetFS(emuthread, GetFS(emu));
et->emu = emuthread;
et->fnc = (uintptr_t)f;
et->arg = arg;
#ifdef DYNAREC
// pre-creation of the JIT code for the entry point of the thread
dynablock_t *current = NULL;
DBGetBlock(emu, (uintptr_t)f, 1, &current);
#endif
*pet = et;
return pthread_routine;
}
void my_longjmp(x86emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int32_t __val);
#define CANCEL_MAX 8
@@ -296,13 +336,13 @@ EXPORT void my___pthread_register_cancel(void* E, void* B)
{
// get a stack local copy of the args, as may be live in some register depending the architecture (like ARM)
if(cancel_deep<0) {
printf_log(LOG_INFO, "BOX86: Warning, inconsistant value in __pthread_register_cancel (%d)\n", cancel_deep);
printf_log(LOG_NONE/*LOG_INFO*/, "BOX86: Warning, inconsistant value in __pthread_register_cancel (%d)\n", cancel_deep);
cancel_deep = 0;
}
if(cancel_deep!=CANCEL_MAX-1)
++cancel_deep;
else
{printf_log(LOG_INFO, "BOX86: Warning, calling __pthread_register_cancel(...) too many time\n");}
{printf_log(LOG_NONE/*LOG_INFO*/, "BOX86: Warning, calling __pthread_register_cancel(...) too many time\n");}
cancel_emu[cancel_deep] = (x86emu_t*)E;
// on i386, the function as __cleanup_fct_attribute attribute: so 1st parameter is in register
@@ -335,12 +375,11 @@ EXPORT void my___pthread_unwind_next(x86emu_t* emu, void* p)
{
// on i386, the function as __cleanup_fct_attribute attribute: so 1st parameter is in register
x86_unwind_buff_t* buff = (x86_unwind_buff_t*)R_EAX;
__pthread_unwind_buf_t *pbuff = AddCancelThread((uintptr_t)buff);
// function is noreturn, so putting stuff on the stack is not a good idea
__pthread_unwind_next(pbuff);
// just in case it does return
// no clear way to clean up this, unless it does return...
__pthread_unwind_buf_t pbuff = *AddCancelThread((uintptr_t)buff);
DelCancelThread((uintptr_t)buff);
// function is noreturn, putting stuff on the stack to have it auto-free (is that correct?)
__pthread_unwind_next(&pbuff);
// just in case it does return
emu->quit = 1;
}
@@ -666,10 +705,10 @@ void init_pthread_helper()
pthread_key_create(&jmpbuf_key, emujmpbuf_destroy);
}
void fini_pthread_helper()
void fini_pthread_helper(box86context_t* context)
{
FreeCancelThread(my_context);
CleanStackSize(my_context);
FreeCancelThread(context);
CleanStackSize(context);
pthread_cond_t *cond;
kh_foreach_value(mapcond, cond,
pthread_cond_destroy(cond);
+982
View File
@@ -0,0 +1,982 @@
#undef _LARGEFILE_SOURCE
#undef _FILE_OFFSET_BITS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <wchar.h>
#include <sys/epoll.h>
#include <fts.h>
#include "x86emu.h"
#include "emu/x86emu_private.h"
#include "debug.h"
#include "vkalign.h"
typedef enum VkStructureType {
VK_STRUCTURE_TYPE_APPLICATION_INFO = 0,
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO = 1,
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO = 2,
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO = 3,
VK_STRUCTURE_TYPE_SUBMIT_INFO = 4,
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO = 5,
VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE = 6,
VK_STRUCTURE_TYPE_BIND_SPARSE_INFO = 7,
VK_STRUCTURE_TYPE_FENCE_CREATE_INFO = 8,
VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO = 9,
VK_STRUCTURE_TYPE_EVENT_CREATE_INFO = 10,
VK_STRUCTURE_TYPE_QUERY_POOL_CREATE_INFO = 11,
VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO = 12,
VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO = 13,
VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO = 14,
VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO = 15,
VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO = 16,
VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO = 17,
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO = 18,
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO = 19,
VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO = 20,
VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO = 21,
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO = 22,
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO = 23,
VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO = 24,
VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO = 25,
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO = 26,
VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO = 27,
VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO = 28,
VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO = 29,
VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO = 30,
VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO = 31,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO = 32,
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO = 33,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO = 34,
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET = 35,
VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET = 36,
VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO = 37,
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO = 38,
VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO = 39,
VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO = 40,
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO = 41,
VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO = 42,
VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO = 43,
VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER = 44,
VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER = 45,
VK_STRUCTURE_TYPE_MEMORY_BARRIER = 46,
VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO = 47,
VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO = 48,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SUBGROUP_PROPERTIES = 1000094000,
VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO = 1000157000,
VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO = 1000157001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES = 1000083000,
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS = 1000127000,
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO = 1000127001,
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO = 1000060000,
VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO = 1000060003,
VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO = 1000060004,
VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO = 1000060005,
VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO = 1000060006,
VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO = 1000060013,
VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO = 1000060014,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES = 1000070000,
VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO = 1000070001,
VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2 = 1000146000,
VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2 = 1000146001,
VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2 = 1000146002,
VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2 = 1000146003,
VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2 = 1000146004,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2 = 1000059000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2 = 1000059001,
VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2 = 1000059002,
VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2 = 1000059003,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2 = 1000059004,
VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2 = 1000059005,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2 = 1000059006,
VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2 = 1000059007,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2 = 1000059008,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES = 1000117000,
VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO = 1000117001,
VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO = 1000117002,
VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO = 1000117003,
VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO = 1000053000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES = 1000053001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES = 1000053002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES = 1000120000,
VK_STRUCTURE_TYPE_PROTECTED_SUBMIT_INFO = 1000145000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_FEATURES = 1000145001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROTECTED_MEMORY_PROPERTIES = 1000145002,
VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2 = 1000145003,
VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO = 1000156000,
VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO = 1000156001,
VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO = 1000156002,
VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO = 1000156003,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES = 1000156004,
VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES = 1000156005,
VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO = 1000085000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO = 1000071000,
VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES = 1000071001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO = 1000071002,
VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES = 1000071003,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES = 1000071004,
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO = 1000072000,
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO = 1000072001,
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO = 1000072002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO = 1000112000,
VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES = 1000112001,
VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO = 1000113000,
VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO = 1000077000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO = 1000076000,
VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES = 1000076001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES = 1000168000,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT = 1000168001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DRAW_PARAMETER_FEATURES = 1000063000,
VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR = 1000001000,
VK_STRUCTURE_TYPE_PRESENT_INFO_KHR = 1000001001,
VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR = 1000060007,
VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR = 1000060008,
VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR = 1000060009,
VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR = 1000060010,
VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_INFO_KHR = 1000060011,
VK_STRUCTURE_TYPE_DEVICE_GROUP_SWAPCHAIN_CREATE_INFO_KHR = 1000060012,
VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR = 1000002000,
VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR = 1000002001,
VK_STRUCTURE_TYPE_DISPLAY_PRESENT_INFO_KHR = 1000003000,
VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR = 1000004000,
VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR = 1000005000,
VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR = 1000006000,
VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR = 1000008000,
VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR = 1000009000,
VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT = 1000011000,
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_RASTERIZATION_ORDER_AMD = 1000018000,
VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT = 1000022000,
VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_TAG_INFO_EXT = 1000022001,
VK_STRUCTURE_TYPE_DEBUG_MARKER_MARKER_INFO_EXT = 1000022002,
VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_IMAGE_CREATE_INFO_NV = 1000026000,
VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_BUFFER_CREATE_INFO_NV = 1000026001,
VK_STRUCTURE_TYPE_DEDICATED_ALLOCATION_MEMORY_ALLOCATE_INFO_NV = 1000026002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT = 1000028000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_PROPERTIES_EXT = 1000028001,
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_STREAM_CREATE_INFO_EXT = 1000028002,
VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD = 1000041000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CORNER_SAMPLED_IMAGE_FEATURES_NV = 1000050000,
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_NV = 1000056000,
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_NV = 1000056001,
VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057000,
VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_NV = 1000057001,
VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_NV = 1000058000,
VK_STRUCTURE_TYPE_VALIDATION_FLAGS_EXT = 1000061000,
VK_STRUCTURE_TYPE_VI_SURFACE_CREATE_INFO_NN = 1000062000,
VK_STRUCTURE_TYPE_IMAGE_VIEW_ASTC_DECODE_MODE_EXT = 1000067000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ASTC_DECODE_FEATURES_EXT = 1000067001,
VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073000,
VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR = 1000073001,
VK_STRUCTURE_TYPE_MEMORY_WIN32_HANDLE_PROPERTIES_KHR = 1000073002,
VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR = 1000073003,
VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR = 1000074000,
VK_STRUCTURE_TYPE_MEMORY_FD_PROPERTIES_KHR = 1000074001,
VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR = 1000074002,
VK_STRUCTURE_TYPE_WIN32_KEYED_MUTEX_ACQUIRE_RELEASE_INFO_KHR = 1000075000,
VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078000,
VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_WIN32_HANDLE_INFO_KHR = 1000078001,
VK_STRUCTURE_TYPE_D3D12_FENCE_SUBMIT_INFO_KHR = 1000078002,
VK_STRUCTURE_TYPE_SEMAPHORE_GET_WIN32_HANDLE_INFO_KHR = 1000078003,
VK_STRUCTURE_TYPE_IMPORT_SEMAPHORE_FD_INFO_KHR = 1000079000,
VK_STRUCTURE_TYPE_SEMAPHORE_GET_FD_INFO_KHR = 1000079001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PUSH_DESCRIPTOR_PROPERTIES_KHR = 1000080000,
VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_CONDITIONAL_RENDERING_INFO_EXT = 1000081000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONDITIONAL_RENDERING_FEATURES_EXT = 1000081001,
VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT = 1000081002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR = 1000082000,
VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR = 1000084000,
VK_STRUCTURE_TYPE_OBJECT_TABLE_CREATE_INFO_NVX = 1000086000,
VK_STRUCTURE_TYPE_INDIRECT_COMMANDS_LAYOUT_CREATE_INFO_NVX = 1000086001,
VK_STRUCTURE_TYPE_CMD_PROCESS_COMMANDS_INFO_NVX = 1000086002,
VK_STRUCTURE_TYPE_CMD_RESERVE_SPACE_FOR_COMMANDS_INFO_NVX = 1000086003,
VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_LIMITS_NVX = 1000086004,
VK_STRUCTURE_TYPE_DEVICE_GENERATED_COMMANDS_FEATURES_NVX = 1000086005,
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_W_SCALING_STATE_CREATE_INFO_NV = 1000087000,
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT = 1000090000,
VK_STRUCTURE_TYPE_DISPLAY_POWER_INFO_EXT = 1000091000,
VK_STRUCTURE_TYPE_DEVICE_EVENT_INFO_EXT = 1000091001,
VK_STRUCTURE_TYPE_DISPLAY_EVENT_INFO_EXT = 1000091002,
VK_STRUCTURE_TYPE_SWAPCHAIN_COUNTER_CREATE_INFO_EXT = 1000091003,
VK_STRUCTURE_TYPE_PRESENT_TIMES_INFO_GOOGLE = 1000092000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PER_VIEW_ATTRIBUTES_PROPERTIES_NVX = 1000097000,
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SWIZZLE_STATE_CREATE_INFO_NV = 1000098000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DISCARD_RECTANGLE_PROPERTIES_EXT = 1000099000,
VK_STRUCTURE_TYPE_PIPELINE_DISCARD_RECTANGLE_STATE_CREATE_INFO_EXT = 1000099001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CONSERVATIVE_RASTERIZATION_PROPERTIES_EXT = 1000101000,
VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_CONSERVATIVE_STATE_CREATE_INFO_EXT = 1000101001,
VK_STRUCTURE_TYPE_HDR_METADATA_EXT = 1000105000,
VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2_KHR = 1000109000,
VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2_KHR = 1000109001,
VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2_KHR = 1000109002,
VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2_KHR = 1000109003,
VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR = 1000109004,
VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO_KHR = 1000109005,
VK_STRUCTURE_TYPE_SUBPASS_END_INFO_KHR = 1000109006,
VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR = 1000111000,
VK_STRUCTURE_TYPE_IMPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114000,
VK_STRUCTURE_TYPE_EXPORT_FENCE_WIN32_HANDLE_INFO_KHR = 1000114001,
VK_STRUCTURE_TYPE_FENCE_GET_WIN32_HANDLE_INFO_KHR = 1000114002,
VK_STRUCTURE_TYPE_IMPORT_FENCE_FD_INFO_KHR = 1000115000,
VK_STRUCTURE_TYPE_FENCE_GET_FD_INFO_KHR = 1000115001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR = 1000119000,
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR = 1000119001,
VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR = 1000119002,
VK_STRUCTURE_TYPE_DISPLAY_PROPERTIES_2_KHR = 1000121000,
VK_STRUCTURE_TYPE_DISPLAY_PLANE_PROPERTIES_2_KHR = 1000121001,
VK_STRUCTURE_TYPE_DISPLAY_MODE_PROPERTIES_2_KHR = 1000121002,
VK_STRUCTURE_TYPE_DISPLAY_PLANE_INFO_2_KHR = 1000121003,
VK_STRUCTURE_TYPE_DISPLAY_PLANE_CAPABILITIES_2_KHR = 1000121004,
VK_STRUCTURE_TYPE_IOS_SURFACE_CREATE_INFO_MVK = 1000122000,
VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK = 1000123000,
VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT = 1000128000,
VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_TAG_INFO_EXT = 1000128001,
VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT = 1000128002,
VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT = 1000128003,
VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT = 1000128004,
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID = 1000129000,
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID = 1000129001,
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID = 1000129002,
VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129003,
VK_STRUCTURE_TYPE_MEMORY_GET_ANDROID_HARDWARE_BUFFER_INFO_ANDROID = 1000129004,
VK_STRUCTURE_TYPE_EXTERNAL_FORMAT_ANDROID = 1000129005,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES_EXT = 1000130000,
VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO_EXT = 1000130001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_FEATURES_EXT = 1000138000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_INLINE_UNIFORM_BLOCK_PROPERTIES_EXT = 1000138001,
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_INLINE_UNIFORM_BLOCK_EXT = 1000138002,
VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_INLINE_UNIFORM_BLOCK_CREATE_INFO_EXT = 1000138003,
VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT = 1000143000,
VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT = 1000143001,
VK_STRUCTURE_TYPE_PIPELINE_SAMPLE_LOCATIONS_STATE_CREATE_INFO_EXT = 1000143002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLE_LOCATIONS_PROPERTIES_EXT = 1000143003,
VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT = 1000143004,
VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR = 1000147000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_FEATURES_EXT = 1000148000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BLEND_OPERATION_ADVANCED_PROPERTIES_EXT = 1000148001,
VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_ADVANCED_STATE_CREATE_INFO_EXT = 1000148002,
VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_TO_COLOR_STATE_CREATE_INFO_NV = 1000149000,
VK_STRUCTURE_TYPE_PIPELINE_COVERAGE_MODULATION_STATE_CREATE_INFO_NV = 1000152000,
VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT = 1000158000,
VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT = 1000158002,
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT = 1000158003,
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT = 1000158004,
VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT = 1000158005,
VK_STRUCTURE_TYPE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160000,
VK_STRUCTURE_TYPE_SHADER_MODULE_VALIDATION_CACHE_CREATE_INFO_EXT = 1000160001,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT = 1000161000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_FEATURES_EXT = 1000161001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DESCRIPTOR_INDEXING_PROPERTIES_EXT = 1000161002,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_ALLOCATE_INFO_EXT = 1000161003,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_VARIABLE_DESCRIPTOR_COUNT_LAYOUT_SUPPORT_EXT = 1000161004,
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_SHADING_RATE_IMAGE_STATE_CREATE_INFO_NV = 1000164000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_FEATURES_NV = 1000164001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADING_RATE_IMAGE_PROPERTIES_NV = 1000164002,
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_COARSE_SAMPLE_ORDER_STATE_CREATE_INFO_NV = 1000164005,
VK_STRUCTURE_TYPE_RAY_TRACING_PIPELINE_CREATE_INFO_NV = 1000165000,
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_CREATE_INFO_NV = 1000165001,
VK_STRUCTURE_TYPE_GEOMETRY_NV = 1000165003,
VK_STRUCTURE_TYPE_GEOMETRY_TRIANGLES_NV = 1000165004,
VK_STRUCTURE_TYPE_GEOMETRY_AABB_NV = 1000165005,
VK_STRUCTURE_TYPE_BIND_ACCELERATION_STRUCTURE_MEMORY_INFO_NV = 1000165006,
VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET_ACCELERATION_STRUCTURE_NV = 1000165007,
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_MEMORY_REQUIREMENTS_INFO_NV = 1000165008,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_RAY_TRACING_PROPERTIES_NV = 1000165009,
VK_STRUCTURE_TYPE_RAY_TRACING_SHADER_GROUP_CREATE_INFO_NV = 1000165011,
VK_STRUCTURE_TYPE_ACCELERATION_STRUCTURE_INFO_NV = 1000165012,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_REPRESENTATIVE_FRAGMENT_TEST_FEATURES_NV = 1000166000,
VK_STRUCTURE_TYPE_PIPELINE_REPRESENTATIVE_FRAGMENT_TEST_STATE_CREATE_INFO_NV = 1000166001,
VK_STRUCTURE_TYPE_DEVICE_QUEUE_GLOBAL_PRIORITY_CREATE_INFO_EXT = 1000174000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_8BIT_STORAGE_FEATURES_KHR = 1000177000,
VK_STRUCTURE_TYPE_IMPORT_MEMORY_HOST_POINTER_INFO_EXT = 1000178000,
VK_STRUCTURE_TYPE_MEMORY_HOST_POINTER_PROPERTIES_EXT = 1000178001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_MEMORY_HOST_PROPERTIES_EXT = 1000178002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_ATOMIC_INT64_FEATURES_KHR = 1000180000,
VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT = 1000184000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_CORE_PROPERTIES_AMD = 1000185000,
VK_STRUCTURE_TYPE_DEVICE_MEMORY_OVERALLOCATION_CREATE_INFO_AMD = 1000189000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT = 1000190000,
VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_DIVISOR_STATE_CREATE_INFO_EXT = 1000190001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_FEATURES_EXT = 1000190002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR = 1000196000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT_CONTROLS_PROPERTIES_KHR = 1000197000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DEPTH_STENCIL_RESOLVE_PROPERTIES_KHR = 1000199000,
VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR = 1000199001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_COMPUTE_SHADER_DERIVATIVES_FEATURES_NV = 1000201000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_FEATURES_NV = 1000202000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MESH_SHADER_PROPERTIES_NV = 1000202001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_SHADER_BARYCENTRIC_FEATURES_NV = 1000203000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_IMAGE_FOOTPRINT_FEATURES_NV = 1000204000,
VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_EXCLUSIVE_SCISSOR_STATE_CREATE_INFO_NV = 1000205000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXCLUSIVE_SCISSOR_FEATURES_NV = 1000205002,
VK_STRUCTURE_TYPE_CHECKPOINT_DATA_NV = 1000206000,
VK_STRUCTURE_TYPE_QUEUE_FAMILY_CHECKPOINT_PROPERTIES_NV = 1000206001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VULKAN_MEMORY_MODEL_FEATURES_KHR = 1000211000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PCI_BUS_INFO_PROPERTIES_EXT = 1000212000,
VK_STRUCTURE_TYPE_IMAGEPIPE_SURFACE_CREATE_INFO_FUCHSIA = 1000214000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_FEATURES_EXT = 1000218000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FRAGMENT_DENSITY_MAP_PROPERTIES_EXT = 1000218001,
VK_STRUCTURE_TYPE_RENDER_PASS_FRAGMENT_DENSITY_MAP_CREATE_INFO_EXT = 1000218002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SCALAR_BLOCK_LAYOUT_FEATURES_EXT = 1000221000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT = 1000237000,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT = 1000238000,
VK_STRUCTURE_TYPE_MEMORY_PRIORITY_ALLOCATE_INFO_EXT = 1000238001,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_BUFFER_ADDRESS_FEATURES_EXT = 1000244000,
VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO_EXT = 1000244001,
VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_CREATE_INFO_EXT = 1000244002,
VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT = 1000246000,
VK_STRUCTURE_TYPE_VALIDATION_FEATURES_EXT = 1000247000,
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT = 1000255002,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT = 1000276000,
VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT,
VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_FEATURES,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTIVIEW_PROPERTIES,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2,
VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2,
VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2,
VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_FORMAT_PROPERTIES_2,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2,
VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO,
VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO,
VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_COMMAND_BUFFER_BEGIN_INFO,
VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_SUBMIT_INFO,
VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_BIND_SPARSE_INFO,
VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_DEVICE_GROUP_INFO,
VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_GROUP_PROPERTIES,
VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DEVICE_GROUP_DEVICE_CREATE_INFO,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO,
VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO,
VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES,
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO,
VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO,
VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO,
VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES,
VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_SEMAPHORE_CREATE_INFO,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES,
VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO,
VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES2_EXT = VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO,
VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES_KHR = VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES,
VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_EXPORT_FENCE_CREATE_INFO,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_POINT_CLIPPING_PROPERTIES,
VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO,
VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO,
VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_DOMAIN_ORIGIN_STATE_CREATE_INFO,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VARIABLE_POINTER_FEATURES,
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS,
VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO,
VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2,
VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2_KHR = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2,
VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2_KHR = VK_STRUCTURE_TYPE_SPARSE_IMAGE_MEMORY_REQUIREMENTS_2,
VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO,
VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO_KHR = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_YCBCR_CONVERSION_FEATURES,
VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES_KHR = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES,
VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO,
VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR = VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO,
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES_KHR = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MAINTENANCE_3_PROPERTIES,
VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT_KHR = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_SUPPORT,
VK_STRUCTURE_TYPE_BEGIN_RANGE = VK_STRUCTURE_TYPE_APPLICATION_INFO,
VK_STRUCTURE_TYPE_END_RANGE = VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO,
VK_STRUCTURE_TYPE_RANGE_SIZE = (VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO - VK_STRUCTURE_TYPE_APPLICATION_INFO + 1),
VK_STRUCTURE_TYPE_MAX_ENUM = 0x7FFFFFFF
} VkStructureType;
typedef struct my_vkhead_s {
VkStructureType sType;
struct my_vkhead_s* pNext;
} my_vkhead_t;
typedef struct my_vksave_s {
struct my_vksave_s* pNext;
my_vkhead_t* pHead;
} my_vksave_t;
typedef struct my_VkPipelineShaderStageCreateInfo_arm_t {
VkStructureType sType;
my_vkhead_t* pNext;
int flags;
int stage;
uint64_t module;
const char* pName;
const void* pSpecializationInfo;
} my_VkPipelineShaderStageCreateInfo_arm_t;
typedef struct my_VkPipelineShaderStageCreateInfo_x86_t {
VkStructureType sType;
my_vkhead_t* pNext;
int flags;
int stage;
uint64_t module;
const char* pName;
const void* pSpecializationInfo;
} __attribute__((packed)) my_VkPipelineShaderStageCreateInfo_x86_t;
typedef struct my_VkComputePipelineCreateInfo_arm_t {
VkStructureType sType;
const my_vkhead_t* pNext;
int flags;
my_VkPipelineShaderStageCreateInfo_arm_t stage;
uint64_t layout;
uint64_t basePipelineHandle;
int32_t basePipelineIndex;
} my_VkComputePipelineCreateInfo_arm_t;
typedef struct my_VkComputePipelineCreateInfo_x86_t {
VkStructureType sType;
const my_vkhead_t* pNext;
int flags;
my_VkPipelineShaderStageCreateInfo_x86_t stage;
uint64_t layout;
uint64_t basePipelineHandle;
int32_t basePipelineIndex;
} __attribute__((packed)) my_VkComputePipelineCreateInfo_x86_t;
#define VK_MAX_PHYSICAL_DEVICE_NAME_SIZE 256
#define VK_UUID_SIZE 16
#define NOCHANGE\
case VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO: \
case VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO: \
case VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO: \
case VK_STRUCTURE_TYPE_DEVICE_GROUP_RENDER_PASS_BEGIN_INFO: \
case VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT: \
case VK_STRUCTURE_TYPE_MEMORY_BARRIER: \
case VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER: \
case VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO: \
case VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO: \
case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO: \
case VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO: \
case VK_STRUCTURE_TYPE_EVENT_CREATE_INFO: \
case VK_STRUCTURE_TYPE_FENCE_CREATE_INFO: \
case VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO: \
case VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO: \
case VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO: \
case VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO: \
case VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO: \
case VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO: \
case VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO: \
case VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO: \
case VK_STRUCTURE_TYPE_MAPPED_MEMORY_RANGE: \
case VK_STRUCTURE_TYPE_BIND_SPARSE_INFO: \
case VK_STRUCTURE_TYPE_BIND_BUFFER_MEMORY_INFO: \
case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO: \
case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO: \
case VK_STRUCTURE_TYPE_BUFFER_MEMORY_REQUIREMENTS_INFO_2: \
case VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2:\
case VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2: \
case VK_STRUCTURE_TYPE_DEVICE_QUEUE_INFO_2: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_BUFFER_INFO: \
case VK_STRUCTURE_TYPE_EXTERNAL_BUFFER_PROPERTIES: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_FENCE_INFO: \
case VK_STRUCTURE_TYPE_EXTERNAL_FENCE_PROPERTIES: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_SEMAPHORE_INFO: \
case VK_STRUCTURE_TYPE_EXTERNAL_SEMAPHORE_PROPERTIES: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2: \
case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2: \
case VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2: \
case VK_STRUCTURE_TYPE_QUEUE_FAMILY_PROPERTIES_2: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SPARSE_IMAGE_FORMAT_INFO_2: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SURFACE_INFO_2_KHR: \
case VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_KHR: \
case VK_STRUCTURE_TYPE_SURFACE_FORMAT_2_KHR: \
case VK_STRUCTURE_TYPE_DEVICE_GROUP_PRESENT_CAPABILITIES_KHR: \
case VK_STRUCTURE_TYPE_PRESENT_INFO_KHR: \
case VK_STRUCTURE_TYPE_DISPLAY_MODE_CREATE_INFO_KHR: \
case VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_2_EXT: \
case VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO: \
case VK_STRUCTURE_TYPE_CALIBRATED_TIMESTAMP_INFO_EXT: \
case VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT: \
case VK_STRUCTURE_TYPE_MULTISAMPLE_PROPERTIES_EXT: \
case VK_STRUCTURE_TYPE_SURFACE_CAPABILITIES_FULL_SCREEN_EXCLUSIVE_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_VERTEX_ATTRIBUTE_DIVISOR_PROPERTIES_EXT: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TRANSFORM_FEEDBACK_FEATURES_EXT: \
case VK_STRUCTURE_TYPE_IMAGE_VIEW_USAGE_CREATE_INFO: \
case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: \
case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO_KHR: \
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SHADER_DEMOTE_TO_HELPER_INVOCATION_FEATURES_EXT:\
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PRIORITY_FEATURES_EXT:\
case VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO: \
#define CH(C, B, A) \
case C: \
s = B; \
A; \
break;
#define CHANGE(A, B) \
CH(VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, "upiUiiup", A) \
CH(VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, "upiUiUU",A) \
CH(VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,"upiiiiuuUiuuuu", A) \
CH(VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, "upiUupuuu", A) \
CH(VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, "upiuppppppppppUUuUi", A) \
CH(VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, "upiUiiiiiiiuuuu", A) \
CH(VK_STRUCTURE_TYPE_SUBMIT_INFO, "upuppupup", A) \
CH(VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, "upUuuuippp", A) \
CH(VK_STRUCTURE_TYPE_COPY_DESCRIPTOR_SET, "upUuuUuuu", A) \
CH(VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2, "upSUUu", A) \
CH(VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, "up" \
"uuuuiYB" \
"SuuuuuuuuuuuUUuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuffuuuffuLUUUiuiuffuuuuiiiiuiiiiiuifuuuuffffffiiUUU"\
"iiiii",A) \
CH(VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR, "upipu", A) \
CH(VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR, "upipu", A) \
CH(VK_STRUCTURE_TYPE_ACQUIRE_NEXT_IMAGE_INFO_KHR, "upUUUUu", A) \
CH(VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR, "upiUuiiuuuiiupiiiiU", A) \
CH(VK_STRUCTURE_TYPE_DISPLAY_SURFACE_CREATE_INFO_KHR, "upiiuuifiuu", A) \
CH(VK_STRUCTURE_TYPE_CONDITIONAL_RENDERING_BEGIN_INFO_EXT, "upUUi", A) \
CH(VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, "upUu", A) \
CH(VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO, "upiupiUiUu", A) \
case VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO: \
B##VkComputePipelineCreateInfo(src, &dst); \
break; \
//--------------------------------------------------------------
//--------- TOOLS --------
//--------------------------------------------------------------
static void checkVkComputePipelineCreateInfo(const char** src, int* dst)
{
*dst = 1;
}
static int needAlign(my_vkhead_t* x86)
{
const char* s;
const char** src = &s;
int dst = 0;
while(x86) {
switch(x86->sType) {
NOCHANGE
break;
CHANGE(return 1, check)
default:
printf_log(LOG_INFO, "BOX86: Warning, unknown Vulkan Type %d in needAlign function\n", x86->sType);
return 0;
}
if(dst) return dst;
x86 = x86->pNext;
}
return 0;
}
static my_vksave_t* saveVk(my_vkhead_t* src)
{
if(!src)
return NULL;
my_vksave_t* ret = malloc(sizeof(my_vksave_t));
ret->pHead = src;
ret->pNext = saveVk(src->pNext);
return ret;
}
static void freeVk(my_vksave_t* save)
{
if(!save)
return;
freeVk(save->pNext);
free(save);
}
//--------------------------------------------------------------
//--------- ALIGN x86 -> ARM --------
//--------------------------------------------------------------
static void alignVkComputePipelineCreateInfo(my_vkhead_t* src, my_vkhead_t** dst)
{
my_VkComputePipelineCreateInfo_arm_t* vkdst = (my_VkComputePipelineCreateInfo_arm_t*)malloc(sizeof(my_VkPipelineShaderStageCreateInfo_arm_t));
my_VkComputePipelineCreateInfo_x86_t* vksrc = (my_VkComputePipelineCreateInfo_x86_t*)src;
vkdst->sType = vksrc->sType;
vkdst->pNext = vksrc->pNext;
vkdst->flags = vksrc->flags;
vkdst->stage.sType = vksrc->stage.sType;
vkdst->stage.pNext = vksrc->stage.pNext;
vkdst->stage.flags = vksrc->stage.flags;
vkdst->stage.stage = vksrc->stage.stage;
vkdst->stage.module = vksrc->stage.module;
vkdst->stage.pName = vksrc->stage.pName;
vkdst->stage.pSpecializationInfo = vksrc->stage.pSpecializationInfo;
vkdst->layout = vksrc->layout;
vkdst->basePipelineHandle = vksrc->basePipelineHandle;
vkdst->basePipelineIndex = vksrc->basePipelineIndex;
}
int vkalignSize(const char* desc)
{
int c = 0;
int sz = 0;
int a = 0;
while(*desc) {
switch (*desc) {
case 'i':
case 'u':
case 'p':
case 'l':
case 'L':
case 'f':
++c;
sz+=4;
break;
case 'S': // start of a struct inside struct. Just align, no copy
if(c&1) {
++c;
sz+=4;
}
break;
case 'B': // 16char, no alignement required
c+=4;
sz+=16;
break;
case 'Y': //256char, no aligment requires
c+=64;
sz+=256;
break;
case 'U':
case 'I':
case 'd':
if(c&1) { //align?
++c;
sz+=4;
}
a=1;
sz+=8;
c+=2;
break;
default:
printf_log(LOG_NONE, "BOX86: Warning, '%c' not handled in vkalignSize!\n", *desc);
}
++desc;
}
if(a && (c&1)) { //align?
++c;
sz+=4;
}
return sz;
}
void* vkalignStruct(void* src, const char* desc, int cnt)
{
int sz = vkalignSize(desc);
int count=(cnt)?cnt:1;
void* dst = (void*)malloc(sz*count);
int c = 0;
int a = 0;
uint32_t* psrc = (uint32_t*)src;
uint32_t* pdst = (uint32_t*)dst;
while(count) {
const char* p = desc;
while(*p) {
switch (*p) {
case 'i':
case 'u':
case 'p':
case 'l':
case 'L':
case 'f':
++c;
*(pdst++) = *(psrc++);
break;
case 'S': // start of a struct inside struct. Just align, no copy
if(c&1) { //align?
++c;
*(pdst++) = 0;
}
break;
case 'B': // 16char, no alignement required
c+=4;
*(pdst++) = *(psrc++);
*(pdst++) = *(psrc++);
*(pdst++) = *(psrc++);
*(pdst++) = *(psrc++);
break;
case 'Y': //256char, no aligment requires
c+=64;
memcpy(pdst, psrc, 256);
pdst+=64;
psrc+=64;
break;
case 'U':
case 'I':
case 'd':
if(c&1) { //align?
++c;
*(pdst++) = 0;
}
*(pdst++) = *(psrc++);
*(pdst++) = *(psrc++);
c+=2;
a=1;
break;
}
++p;
}
if(a && (c&1)) {
++c;
++pdst;
}
--count;
}
return dst;
}
static my_vkhead_t* alignFromx86(my_vkhead_t* src)
{
if(!src)
return src;
my_vkhead_t *dst = src;
const char* s;
switch(src->sType) {
NOCHANGE
// no need to align...
break;
CHANGE(dst=vkalignStruct(src, s, 0), align)
default:
// unknow
printf_log(LOG_INFO, "BOX86: Warning, unknown Vulkan structure type %d\n", src->sType);
}
dst->pNext = alignFromx86(src->pNext);
return dst;
}
void* VulkanFromx86(void* src, void** save)
{
if(!src)
return src;
if(!needAlign(src))
return src;
*save = saveVk(src);
return alignFromx86(src);
}
//--------------------------------------------------------------
//--------- UNALIGN ARM -> x86 --------
//--------------------------------------------------------------
static void unalignVkComputePipelineCreateInfo(my_vkhead_t* src, my_vkhead_t** dst)
{
my_VkComputePipelineCreateInfo_x86_t* vkdst = (my_VkComputePipelineCreateInfo_x86_t*)*dst;
my_VkComputePipelineCreateInfo_arm_t* vksrc = (my_VkComputePipelineCreateInfo_arm_t*)src;
vkdst->sType = vksrc->sType;
vkdst->pNext = vksrc->pNext;
vkdst->flags = vksrc->flags;
vkdst->stage.sType = vksrc->stage.sType;
vkdst->stage.pNext = vksrc->stage.pNext;
vkdst->stage.flags = vksrc->stage.flags;
vkdst->stage.stage = vksrc->stage.stage;
vkdst->stage.module = vksrc->stage.module;
vkdst->stage.pName = vksrc->stage.pName;
vkdst->stage.pSpecializationInfo = vksrc->stage.pSpecializationInfo;
vkdst->layout = vksrc->layout;
vkdst->basePipelineHandle = vksrc->basePipelineHandle;
vkdst->basePipelineIndex = vksrc->basePipelineIndex;
free(src);
}
void vkunalignStruct(void* dst, void* src, const char* desc, int cnt)
{
int c = 0;
int a = 1;
uint32_t* psrc = (uint32_t*)src;
uint32_t* pdst = (uint32_t*)dst;
int count = (cnt)?cnt:1;
while(count) {
const char* p = desc;
while(*p) {
switch (*p) {
case 'i':
case 'u':
case 'p':
case 'f':
case 'l':
case 'L':
++c;
*(pdst++) = *(psrc++);
break;
case 'S': // start of a struct inside struct. Just align, no copy
if(c&1) { //align?
++c;
++psrc;
}
break;
case 'B': // 16char, no alignement required
c+=4;
*(pdst++) = *(psrc++);
*(pdst++) = *(psrc++);
*(pdst++) = *(psrc++);
*(pdst++) = *(psrc++);
break;
case 'Y': //256char, no aligment requires
c+=64;
memcpy(pdst, psrc, 256);
pdst+=64;
psrc+=64;
break;
case 'U':
case 'I':
case 'd':
if(c&1) { //align?
++c;
++psrc;
}
*(pdst++) = *(psrc++);
*(pdst++) = *(psrc++);
c+=2;
a=1;
break;
}
++p;
}
--count;
if(a && (c&1)) { //align?
++c;
++psrc;
}
}
free(src);
}
int vkunalignSize(const char* desc)
{
int sz = 0;
while(*desc) {
switch (*desc) {
case 'i':
case 'u':
case 'p':
case 'l':
case 'L':
case 'f':
sz+=4;
break;
case 'S': // start of a struct inside struct. Just align, no copy
break;
case 'B': // 16char, no alignement required
sz+=16;
break;
case 'Y': //256char, no aligment requires
sz+=256;
break;
case 'U':
case 'I':
case 'd':
sz+=8;
break;
default:
printf_log(LOG_NONE, "BOX86: Warning, '%c' not handled in vkunalignSize!\n", *desc);
}
++desc;
}
return sz;
}
void* vkStructUnalign(void* src, const char* desc, int cnt)
{
int sz = vkunalignSize(desc);
int count=cnt;
if(!cnt && !src)
return src;
void* dst = (void*)malloc(sz*count);
int c = 0;
int a = 1;
uint32_t* psrc = (uint32_t*)src;
uint32_t* pdst = (uint32_t*)dst;
while(count) {
const char* p = desc;
while(*p) {
switch (*p) {
case 'i':
case 'u':
case 'p':
case 'f':
case 'l':
case 'L':
++c;
*(pdst++) = *(psrc++);
break;
case 'S': // start of a struct inside struct. Just align, no copy
if(c&1) { //align?
++c;
++psrc;
}
break;
case 'B': // 16char, no alignement required
c+=4;
*(pdst++) = *(psrc++);
*(pdst++) = *(psrc++);
*(pdst++) = *(psrc++);
*(pdst++) = *(psrc++);
break;
case 'Y': //256char, no aligment requires
c+=64;
memcpy(pdst, psrc, 256);
pdst+=64;
psrc+=64;
break;
case 'U':
case 'I':
case 'd':
if(c&1) { //align?
++c;
++psrc;
}
*(pdst++) = *(psrc++);
*(pdst++) = *(psrc++);
c+=2;
a=1;
break;
}
++p;
}
--count;
if(a && (c&1)) { //align?
++c;
++psrc;
}
}
return dst;
}
static void unalignFromx86(my_vkhead_t* src, my_vksave_t* vksave)
{
my_vkhead_t* dst = vksave->pHead;
while(src) {
my_vkhead_t* nextsrc = src->pNext;
const char* s;
switch(src->sType) {
NOCHANGE
// no need to unalign...
break;
CHANGE(vkunalignStruct(dst, src, s, 0), unalign)
default:
break;// unknown
}
vksave = vksave->pNext;
dst->pNext = vksave?vksave->pHead:NULL;
dst = dst->pNext;
src = nextsrc;
}
}
void VulkanTox86(void* src, void* save)
{
if(!src || !save)
return;
my_vkhead_t* vksrc = (my_vkhead_t*)src;
my_vksave_t* vksave = (my_vksave_t*)save;
unalignFromx86(vksrc, vksave);
freeVk(save);
}
+9
View File
@@ -0,0 +1,9 @@
#include <stdint.h>
void* VulkanFromx86(void* src, void** save);
void VulkanTox86(void* src, void* save);
int vkalignSize(const char* desc);
void* vkalignStruct(void* src, const char* desc, int cnt);
void vkunalignStruct(void* dst, void* src, const char* desc, int cnt);
void* vkStructUnalign(void* src, const char* desc, int cnt);
+173 -21
View File
@@ -17,6 +17,9 @@
#include <limits.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <signal.h>
#include <sys/syscall.h>
#ifdef DYNAREC
#ifdef ARM
#include <linux/auxvec.h>
@@ -50,6 +53,7 @@ int box86_dynarec_linker = 1;
int box86_dynarec_forced = 0;
int box86_dynarec_largest = 0;
int box86_dynarec_smc = 0;
int box86_dynarec_safemmap = 0;
#ifdef ARM
int arm_vfp = 0; // vfp version (3 or 4), with 32 registers is mendatory
int arm_swap = 0;
@@ -70,19 +74,25 @@ int box86_dynarec_trace = 0;
#ifdef PANDORA
int x11color16 = 0;
#endif
#ifdef RPI
int box86_tokitori2 = 0;
#endif
int box86_zoom = 0;
int x11threads = 0;
int x11glx = 1;
int allow_missing_libs = 0;
int fix_64bit_inodes = 0;
int box86_steam = 0;
int box86_nopulse = 0;
int box86_nogtk = 0;
char* libGL = NULL;
uintptr_t trace_start = 0, trace_end = 0;
char* trace_func = NULL;
uintptr_t fmod_smc_start = 0;
uintptr_t fmod_smc_end = 0;
uint16_t default_fs = 0;
uint32_t default_fs = 0;
int jit_gdb = 0;
int box86_tcmalloc_minimal = 0;
FILE* ftrace = NULL;
int ftrace_has_pid = 0;
@@ -110,7 +120,8 @@ void openFTrace()
ftrace = stdout;
printf_log(LOG_INFO, "Cannot open trace file \"%s\" for writing (error=%s)\n", p, strerror(errno));
} else {
printf("BOX86 Trace redirected to \"%s\"\n", p);
if(!box86_nobanner)
printf("BOX86 Trace redirected to \"%s\"\n", p);
}
}
}
@@ -186,7 +197,14 @@ EXPORTDYN
void LoadLogEnv()
{
ftrace = stdout;
const char *p = getenv("BOX86_LOG");
const char *p = getenv("BOX86_NOBANNER");
if(p) {
if(strlen(p)==1) {
if(p[0]>='0' && p[1]<='1')
box86_nobanner = p[0]-'0';
}
}
p = getenv("BOX86_LOG");
if(p) {
if(strlen(p)==1) {
if(p[0]>='0'+LOG_NONE && p[1]<='0'+LOG_DEBUG)
@@ -201,15 +219,8 @@ void LoadLogEnv()
else if(!strcasecmp(p, "DUMP"))
box86_log = LOG_DUMP;
}
printf_log(LOG_INFO, "Debug level is %d\n", box86_log);
}
p = getenv("BOX86_NOBANNER");
if(p) {
if(strlen(p)==1) {
if(p[0]>='0' && p[1]<='1')
box86_nobanner = p[0]-'0';
}
printf_log(LOG_INFO, "Dynarec is %s\n", box86_nobanner?"On":"Off");
if(!box86_nobanner)
printf_log(LOG_INFO, "Debug level is %d\n", box86_log);
}
#ifdef DYNAREC
p = getenv("BOX86_DYNAREC_DUMP");
@@ -271,6 +282,14 @@ void LoadLogEnv()
if(box86_dynarec_smc)
printf_log(LOG_INFO, "Dynarec is trying to detect SMC in same dynablock\n");
}
p = getenv("BOX86_DYNAREC_SAFEMMAP");
if(p) {
if(strlen(p)==1) {
if(p[0]>='0' && p[1]<='1')
box86_dynarec_safemmap = p[0]-'0';
}
printf_log(LOG_INFO, "Dynarec Safe mmap is %s\n", box86_dynarec_safemmap?"On":"Off");
}
#endif
#ifdef HAVE_TRACE
p = getenv("BOX86_TRACE_XMM");
@@ -374,6 +393,15 @@ void LoadLogEnv()
if(box86_nopulse)
printf_log(LOG_INFO, "Disable the use of pulseaudio libs\n");
}
p = getenv("BOX86_NOGTK");
if(p) {
if(strlen(p)==1) {
if(p[0]>='0' && p[1]<='0'+1)
box86_nogtk = p[0]-'0';
}
if(box86_nogtk)
printf_log(LOG_INFO, "Disable the use of wraped gtk libs\n");
}
p = getenv("BOX86_FIX_64BIT_INODES");
if(p) {
if(strlen(p)==1) {
@@ -524,6 +552,7 @@ void PrintHelp() {
printf(" BOX86_LD_PRELOAD=XXXX[:YYYYY] force loading XXXX (and YYYY...) libraries with the binary\n");
printf(" BOX86_ALLOWMISSINGLIBS with 1 to allow to continue even if a lib is missing (unadvised, will probably crash later)\n");
printf(" BOX86_NOPULSE=1 to disable the loading of pulseaudio libs\n");
printf(" BOX86_NOGTK=1 to disable the loading of wrapped gtk libs\n");
printf(" BOX86_JITGDB with 1 to launch \"gdb\" when a segfault is trapped, attached to the offending process\n");
}
@@ -680,10 +709,47 @@ void endBox86()
printf_log(LOG_DEBUG, "Calling atexit registered functions\n");
CallAllCleanup(emu);
// than call all the Fini (some "smart" ordering of the fini may be needed, but for now, callign in this order should be good enough)
printf_log(LOG_DEBUG, "Calling fini for all loaded elfs\n");
for (int i=0; i<my_context->elfsize; ++i)
RunElfFini(my_context->elfs[i], emu);
printf_log(LOG_DEBUG, "Calling fini for all loaded elfs and unload native libs\n");
RunElfFini(my_context->elfs[0], emu);
FreeLibrarian(&my_context->maplib); // unload all libs
FreeLibrarian(&my_context->local_maplib); // unload all libs
// waiting for all thread except this one to finish
int this_thread = GetTID();
int pid = getpid();
int running = 1;
int attempt = 0;
printf_log(LOG_DEBUG, "Waiting for all threads to finish before unloading box86context\n");
while(running) {
DIR *proc_dir;
char dirname[100];
snprintf(dirname, sizeof dirname, "/proc/self/task");
proc_dir = opendir(dirname);
running = 0;
if (proc_dir)
{
struct dirent *entry;
while ((entry = readdir(proc_dir)) != NULL && !running)
{
if(entry->d_name[0] == '.')
continue;
int tid = atoi(entry->d_name);
// tid != pthread_t, so no pthread functions are available here
if(tid!=this_thread) {
if(attempt>4000) {
printf_log(LOG_INFO, "Stop waiting for remaining thread %04d\n", tid);
// enough wait, kill all thread!
syscall(__NR_tgkill, pid, tid, SIGABRT);
} else {
running = 1;
++attempt;
sched_yield();
}
}
}
closedir(proc_dir);
}
}
// all done, free context
FreeBox86Context(&my_context);
if(libGL) {
@@ -737,9 +803,10 @@ static void free_contextargv()
free(my_context->argv[i]);
}
const char **environ __attribute__((weak)) = NULL;
int main(int argc, const char **argv, const char **env) {
init_auxval(argc, argv, env);
init_auxval(argc, argv, environ?environ:env);
// trying to open and load 1st arg
if(argc==1) {
PrintBox86Version();
@@ -793,6 +860,11 @@ int main(int argc, const char **argv, const char **env) {
const char* prereserve = getenv("WINEPRELOADRESERVE");
printf_log(LOG_INFO, "BOX86: Wine detected, WINEPRELOADRESERVE=\"%s\"\n", prereserve?prereserve:"");
wine_prereserve(prereserve);
// special case for winedbg, doesn't work anyway
if(argv[nextarg+1] && strstr(argv[nextarg+1], "winedbg")==argv[nextarg+1]) {
printf_log(LOG_NONE, "winedbg detected, not launching it!\n");
exit(0); // exiting, it doesn't work anyway
}
}
// Create a new context
my_context = NewBox86Context(argc - nextarg);
@@ -805,11 +877,11 @@ int main(int argc, const char **argv, const char **env) {
else
my_context->box86path = ResolveFile(argv[0], &my_context->box86_path);
// prepare all other env. var
my_context->envc = CountEnv(env);
my_context->envc = CountEnv(environ?environ:env);
printf_log(LOG_INFO, "Counted %d Env var\n", my_context->envc);
// allocate extra space for new environment variables such as BOX86_PATH
my_context->envv = (char**)calloc(my_context->envc+4, sizeof(char*));
GatherEnv(&my_context->envv, env, my_context->box86path);
GatherEnv(&my_context->envv, environ?environ:env, my_context->box86path);
if(box86_log>=LOG_DUMP) {
for (int i=0; i<my_context->envc; ++i)
printf_log(LOG_DUMP, " Env[%02d]: %s\n", i, my_context->envv[i]);
@@ -828,6 +900,8 @@ int main(int argc, const char **argv, const char **env) {
} else {
if(getenv("LD_PRELOAD")) {
char* p = getenv("LD_PRELOAD");
if(strstr(p, "libtcmalloc_minimal.so.4"))
box86_tcmalloc_minimal = 1;
ParseList(p, &ld_preload, 0);
if (ld_preload.size && box86_log) {
printf_log(LOG_INFO, "BOX86 try to Preload ");
@@ -875,6 +949,25 @@ int main(int argc, const char **argv, const char **env) {
free(my_context->argv[0]);
my_context->argv[0] = strdup("./UnrealLinux.bin");
}
#ifdef RPI
// special case for TokiTori 2+, that check if texture max size is > = 8192
if(strstr(prgname, "TokiTori2.bin.x86")==prgname) {
printf_log(LOG_INFO, "TokiTori 2+ detected, runtime patch to fix GPU non-power-of-two faillure\n");
box86_tokitori2 = 1;
}
#endif
// special case for zoom
if(strstr(prgname, "zoom")==prgname) {
printf_log(LOG_INFO, "Zoom detected, trying to use system libturbojpeg if possible\n");
box86_zoom = 1;
}
/*if(strstr(prgname, "awesomium_process")==prgname) {
printf_log(LOG_INFO, "awesomium_process detected, forcing emulated libpng12\n");
AddPath("libpng12.so.0", &my_context->box86_emulated_libs, 0);
}*/
/*if(!strcmp(prgname, "gdb")) {
exit(-1);
}*/
for(int i=1; i<my_context->argc; ++i) {
my_context->argv[i] = strdup(argv[i+nextarg]);
@@ -908,12 +1001,12 @@ int main(int argc, const char **argv, const char **env) {
}
elfheader_t *elf_header = LoadAndCheckElfHeader(f, my_context->argv[0], 1);
if(!elf_header) {
printf_log(LOG_NONE, "Error: reading elf header of %s\n", my_context->argv[0]);
printf_log(LOG_NONE, "Error: reading elf header of %s, try to launch natively instead\n", my_context->argv[0]);
fclose(f);
free_contextargv();
FreeBox86Context(&my_context);
FreeCollection(&ld_preload);
return -1;
return execvp(argv[1], (char * const*)(argv+1));
}
AddElfHeader(my_context, elf_header);
@@ -945,6 +1038,52 @@ int main(int argc, const char **argv, const char **env) {
}
// can close the file now
fclose(f);
if(ElfCheckIfUseTCMallocMinimal(elf_header)) {
if(!box86_tcmalloc_minimal) {
// need to reload with tcmalloc_minimal as a LD_PRELOAD!
printf_log(LOG_INFO, "BOX86: tcmalloc_minimal.so.4 used, reloading box86 with the lib preladed\n");
// need to get a new envv variable. so first count it and check if LD_PRELOAD is there
int preload=(getenv("LD_PRELOAD"))?1:0;
int nenv = 0;
while(env[nenv]) nenv++;
// alloc + "LD_PRELOAD" if needd + last NULL ending
char** newenv = (char**)calloc(nenv+1+((preload)?0:1), sizeof(char*));
// copy strings
for (int i=0; i<nenv; ++i)
newenv[i] = strdup(env[i]);
// add ld_preload
if(preload) {
// find the line
int l = 0;
while(l<nenv) {
if(strstr(newenv[l], "LD_PRELOAD=")==newenv[l]) {
// found it!
char *old = newenv[l];
newenv[l] = (char*)calloc(strlen(old)+strlen("libtcmalloc_minimal.so.4:")+1, sizeof(char));
strcpy(newenv[l], "LD_PRELOAD=libtcmalloc_minimal.so.4:");
strcat(newenv[l], old + strlen("LD_PRELOAD="));
free(old);
// done, end loop
l = nenv;
} else ++l;
}
} else {
//move last one
newenv[nenv] = strdup(newenv[nenv-1]);
free(newenv[nenv-1]);
newenv[nenv-1] = strdup("LD_PRELOAD=libtcmalloc_minimal.so.4");
}
// duplicate argv too
char** newargv = calloc(argc+1, sizeof(char*));
int narg = 0;
while(argv[narg]) {newargv[narg] = strdup(argv[narg]); narg++;}
// launch with new env...
if(execve(newargv[0], newargv, newenv)<0)
printf_log(LOG_NONE, "Failed to relaunch, error is %d/%s\n", errno, strerror(errno));
} else {
printf_log(LOG_INFO, "BOX86: Using tcmalloc_minimal.so.4, and it's in the LD_PRELOAD command\n");
}
}
// get and alloc stack size and align
if(CalcStackSize(my_context)) {
printf_log(LOG_NONE, "Error: allocating stack\n");
@@ -953,6 +1092,16 @@ int main(int argc, const char **argv, const char **env) {
FreeCollection(&ld_preload);
return -1;
}
#ifdef RPI
if(box86_tokitori2) {
uint32_t *patch = (uint32_t*)0x85897f4;
if(*patch==0x2000) {
*patch = 0x1000;
printf_log(LOG_NONE, "Runtime patching the game\n");
} else
printf_log(LOG_NONE, "Cannot patch the game\n");
}
#endif
// init x86 emu
x86emu_t *emu = NewX86Emu(my_context, my_context->ep, (uintptr_t)my_context->stack, my_context->stacksz, 0);
// stack setup is much more complicated then just that!
@@ -978,6 +1127,9 @@ int main(int argc, const char **argv, const char **env) {
*(void**)wineinfo = get_wine_prereserve();
printf_log(LOG_DEBUG, "WINE wine_main_preload_info found and updated\n");
}
#ifdef DYNAREC
dynarec_wine_prereserve();
#endif
}
// pre-load lib if needed
if(ld_preload.size) {
@@ -1011,7 +1163,7 @@ int main(int argc, const char **argv, const char **env) {
setupTrace(my_context);
// get entrypoint
my_context->ep = GetEntryPoint(my_context->maplib, elf_header);
#ifdef RPI
#if defined(RPI) || defined(RK3399)
// before launching emulation, let's check if this is a mojosetup from GOG
if (((strstr(prog, "bin/linux/x86/mojosetup") && getenv("MOJOSETUP_BASE")) || strstr(prog, ".mojosetup/mojosetup"))
&& getenv("GTK2_RC_FILES")) {
+94 -6
View File
@@ -1,11 +1,19 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <dlfcn.h>
#include "bridge.h"
#include "bridge_private.h"
#include "wrapper.h"
#include "khash.h"
#include "debug.h"
#include "x86emu.h"
#ifdef DYNAREC
#include "dynablock.h"
#include "box86context.h"
#endif
KHASH_MAP_INIT_INT(bridgemap, uintptr_t)
@@ -46,13 +54,13 @@ void FreeBridge(bridge_t** bridge)
*bridge = NULL;
}
uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N)
uintptr_t AddBridge(bridge_t* bridge, box86context_t* context, wrapper_t w, void* fnc, int N)
{
brick_t *b = bridge->last;
if(b->sz == NBRICK) {
b->next = (brick_t*)calloc(1, sizeof(brick_t));
b = b->next;
bridge->head = b;
bridge->last = b;
}
b->b[b->sz].CC = 0xCC;
b->b[b->sz].S = 'S'; b->b[b->sz].C='C';
@@ -64,6 +72,10 @@ uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N)
int ret;
khint_t k = kh_put(bridgemap, bridge->bridgemap, (uintptr_t)fnc, &ret);
kh_value(bridge->bridgemap, k) = (uintptr_t)&b->b[b->sz].CC;
#ifdef DYNAREC
if(box86_dynarec)
addDBFromAddressRange(context, (uintptr_t)&b->b[b->sz].CC, sizeof(onebridge_t), 0);
#endif
return (uintptr_t)&b->b[b->sz++].CC;
}
@@ -77,19 +89,56 @@ uintptr_t CheckBridged(bridge_t* bridge, void* fnc)
return kh_value(bridge->bridgemap, k);
}
uintptr_t AddCheckBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N)
uintptr_t AddCheckBridge(bridge_t* bridge, box86context_t* context, wrapper_t w, void* fnc, int N)
{
if(!fnc)
return 0;
uintptr_t ret = CheckBridged(bridge, fnc);
if(!ret)
ret = AddBridge(bridge, w, fnc, N);
ret = AddBridge(bridge, context, w, fnc, N);
return ret;
}
uintptr_t AddAutomaticBridge(x86emu_t* emu, bridge_t* bridge, wrapper_t w, void* fnc, int N)
{
if(!fnc)
return 0;
uintptr_t ret = CheckBridged(bridge, fnc);
if(!ret)
ret = AddBridge(bridge, GetEmuContext(emu), w, fnc, N);
if(!hasAlternate(fnc)) {
printf_log(LOG_DEBUG, "Adding AutomaticBridge for %p to %p\n", fnc, (void*)ret);
addAlternate(fnc, (void*)ret);
#ifdef DYNAREC
// now, check if dynablock at native address exist
DBAlternateBlock(emu, (uintptr_t)fnc, ret);
#endif
}
return ret;
}
void* GetNativeFnc(uintptr_t fnc)
{
if(!fnc) return NULL;
// check if function exist in some loaded lib
Dl_info info;
if(dladdr((void*)fnc, &info))
return (void*)fnc;
// check if it's an indirect jump
#define PK(a) *(uint8_t*)(fnc+a)
#define PK32(a) *(uint32_t*)(fnc+a)
if(PK(0)==0xff && PK(1)==0x25) { // absolute jump, maybe the GOT
uintptr_t a1 = (PK32(2)); // need to add a check to see if the address is from the GOT !
a1 = *(uintptr_t*)a1;
if(a1 && a1>0x10000) {
a1 = (uintptr_t)GetNativeFnc(a1);
if(a1)
return (void*)a1;
}
}
#undef PK
#undef PK32
// check if bridge exist
onebridge_t *b = (onebridge_t*)fnc;
if(b->CC != 0xCC || b->S!='S' || b->C!='C' || (b->C3!=0xC3 && b->C3!=0xC2))
return NULL; // not a bridge?!
@@ -102,4 +151,43 @@ void* GetNativeFncOrFnc(uintptr_t fnc)
if(b->CC != 0xCC || b->S!='S' || b->C!='C' || (b->C3!=0xC3 && b->C3!=0xC2))
return (void*)fnc; // not a bridge?!
return (void*)b->f;
}
}
// Alternate address handling
KHASH_MAP_INIT_INT(alternate, void*)
static kh_alternate_t *my_alternates = NULL;
int hasAlternate(void* addr) {
if(!my_alternates)
return 0;
khint_t k = kh_get(alternate, my_alternates, (uintptr_t)addr);
if(k==kh_end(my_alternates))
return 0;
return 1;
}
void* getAlternate(void* addr) {
if(!my_alternates)
return addr;
khint_t k = kh_get(alternate, my_alternates, (uintptr_t)addr);
if(k!=kh_end(my_alternates))
return kh_value(my_alternates, k);
return addr;
}
void addAlternate(void* addr, void* alt) {
if(!my_alternates) {
my_alternates = kh_init(alternate);
}
int ret;
khint_t k = kh_put(alternate, my_alternates, (uintptr_t)addr, &ret);
if(!ret) // already there
return;
kh_value(my_alternates, k) = alt;
}
void cleanAlternate() {
if(my_alternates) {
kh_destroy(alternate, my_alternates);
my_alternates = NULL;
}
}
-265
View File
@@ -12,245 +12,6 @@
#include "box86context.h"
#include "box86stack.h"
#include "dynarec.h"
#include "khash.h"
typedef struct onecallback_s onecallback_t;
typedef struct onecallback_s {
x86emu_t *emu;
uintptr_t fnc;
int nb_args;
void* arg[10];
int shared;
onecallback_t *chain;
} onecallback_t;
KHASH_MAP_INIT_INT(callbacks, onecallback_t*)
typedef struct callbacklist_s {
kh_callbacks_t *list;
int cap;
int sz;
} callbacklist_t;
onecallback_t* FindCallback(x86emu_t* emu)
{
if(!emu)
return NULL;
// find the callback first
callbacklist_t *callbacks = emu->context->callbacks;
khint_t k = kh_get(callbacks, callbacks->list, (uintptr_t)emu);
if(k==kh_end(callbacks->list) || !kh_exist(callbacks->list, k))
return NULL;
return kh_value(callbacks->list, k);
}
x86emu_t* FindCallbackFnc1Arg(x86emu_t* emu, uintptr_t fnc, int argn, void* arg)
{
if(!emu)
return NULL;
// find the callback first
callbacklist_t *callbacks = emu->context->callbacks;
onecallback_t* cb;
kh_foreach_value(callbacks->list, cb,
if(cb->fnc==fnc && cb->arg[argn]==arg)
return cb->emu;
);
return NULL;
}
int IsCallback(box86context_t* context, x86emu_t* cb)
{
if(!cb)
return 0;
callbacklist_t *callbacks = context->callbacks;
khint_t k = kh_get(callbacks, callbacks->list, (uintptr_t)cb);
if(k==kh_end(callbacks->list) || !kh_exist(callbacks->list, k))
return 0;
return 1;
}
x86emu_t* AddVariableCallback(x86emu_t* emu, int stsize, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4)
{
callbacklist_t *callbacks = emu->context->callbacks;
void* stack = calloc(1, stsize);
if(!stack) {
printf_log(LOG_NONE, "BOX86: Error, cannot allocate %d KB Stack for callback\n", stsize/1024);
}
x86emu_t * newemu = NewX86Emu(emu->context, fnc, (uintptr_t)stack, stsize, 1);
SetupX86Emu(newemu);
onecallback_t * cb;
int ret;
khint_t k = kh_put(callbacks, callbacks->list, (uintptr_t)newemu, &ret);
cb = kh_value(callbacks->list, k) = (onecallback_t*)calloc(1, sizeof(onecallback_t));
cb->emu = newemu;
cb->fnc = fnc;
cb->nb_args = nb_args;
cb->arg[0] = arg1;
cb->arg[1] = arg2;
cb->arg[2] = arg3;
cb->arg[3] = arg4;
cb->shared = 0;
return newemu;
}
x86emu_t* AddCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4)
{
// 2MB stack (1MB is not enough for Xenonauts)
return AddVariableCallback(emu, 2*1024*1024, fnc, nb_args, arg1, arg2, arg3, arg4);
}
x86emu_t* AddSmallCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4)
{
// 64KB stack
return AddVariableCallback(emu, 64*1024, fnc, nb_args, arg1, arg2, arg3, arg4);
}
x86emu_t* AddSharedCallback(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1, void* arg2, void* arg3, void* arg4)
{
callbacklist_t *callbacks = emu->context->callbacks;
x86emu_t * newemu = emu;
onecallback_t * cb;
onecallback_t * old = FindCallback(emu);
int ret;
khint_t k = kh_put(callbacks, callbacks->list, (uintptr_t)newemu, &ret);
cb = kh_value(callbacks->list, k) = (onecallback_t*)calloc(1, sizeof(onecallback_t));
cb->emu = newemu;
cb->fnc = fnc;
cb->nb_args = nb_args;
cb->arg[0] = arg1;
cb->arg[1] = arg2;
cb->arg[2] = arg3;
cb->arg[3] = arg4;
cb->shared = 1;
cb->chain = old;
return newemu;
}
x86emu_t* GetCallback1Arg(x86emu_t* emu, uintptr_t fnc, int nb_args, void* arg1)
{
callbacklist_t *callbacks = emu->context->callbacks;
onecallback_t * cb;
kh_foreach_value(callbacks->list, cb,
if(cb->fnc==fnc && cb->nb_args==nb_args && cb->arg[0]==arg1) {
return cb->emu;
}
);
return NULL;
}
x86emu_t* FreeCallback(x86emu_t* emu)
{
// find the callback first
callbacklist_t *callbacks = emu->context->callbacks;
khint_t k = kh_get(callbacks, callbacks->list, (uintptr_t)emu);
if(k==kh_end(callbacks->list))
return emu;
onecallback_t* cb = kh_value(callbacks->list, k);
if(!cb->shared)
FreeX86Emu(&cb->emu);
x86emu_t* ret = NULL;
if(cb->chain) {
kh_value(callbacks->list, k) = cb->chain; // unchain, in case of shared callback inside callback
ret = cb->chain->emu;
} else {
kh_del(callbacks, callbacks->list, k);
}
free(cb);
return ret;
}
uint32_t RunCallback(x86emu_t* emu)
{
onecallback_t *cb = FindCallback(emu);
if(cb) {
// clean seg offs cache
memset(emu->segs_clean, 0, sizeof(emu->segs_clean));
for (int i=cb->nb_args-1; i>=0; --i) // reverse order
Push(emu, (uint32_t)cb->arg[i]);
DynaCall(emu, cb->fnc);
R_ESP+=(cb->nb_args*4);
return R_EAX;
}
printf_log(LOG_INFO, "Warning, Callback not found?!\n");
return 0;
}
void SetCallbackArg(x86emu_t* emu, int arg, void* val)
{
onecallback_t *cb = FindCallback(emu);
if(cb) {
cb->arg[arg] = val;
}
}
void SetCallbackNArg(x86emu_t* emu, int narg)
{
onecallback_t *cb = FindCallback(emu);
if(cb) {
cb->nb_args = narg;
}
}
void* GetCallbackArg(x86emu_t* emu, int arg)
{
onecallback_t *cb = FindCallback(emu);
if(cb) {
return cb->arg[arg];
}
return NULL;
}
void SetCallbackAddress(x86emu_t* emu, uintptr_t address)
{
onecallback_t *cb = FindCallback(emu);
if(cb) {
cb->fnc = address;
}
}
uintptr_t GetCallbackAddress(x86emu_t* emu)
{
onecallback_t *cb = FindCallback(emu);
if(cb) {
return cb->fnc;
}
return 0;
}
callbacklist_t* NewCallbackList()
{
callbacklist_t* callbacks = (callbacklist_t*)calloc(1, sizeof(callbacklist_t));
callbacks->list = kh_init(callbacks);
return callbacks;
}
void FreeCallbackList(callbacklist_t** callbacks)
{
if(!callbacks)
return;
if(!*callbacks)
return;
onecallback_t* cb;
kh_foreach_value((*callbacks)->list, cb,
FreeX86Emu(&cb->emu);
free(cb);
);
kh_destroy(callbacks, (*callbacks)->list);
free(*callbacks);
*callbacks = NULL;
}
EXPORTDYN
uint32_t RunFunction(box86context_t *context, uintptr_t fnc, int nargs, ...)
@@ -302,32 +63,6 @@ uint64_t RunFunction64(box86context_t *context, uintptr_t fnc, int nargs, ...)
return ret;
}
void SetCallbackArgs(x86emu_t* emu, int nargs, ...)
{
onecallback_t *cb = FindCallback(emu);
if(cb) {
va_list va;
va_start (va, nargs);
for (int i=0; i<nargs; ++i) {
cb->arg[i] = va_arg(va, void*);
}
va_end (va);
}
}
void SetCallbackNArgs(x86emu_t* emu, int N, int nargs, ...)
{
onecallback_t *cb = FindCallback(emu);
if(cb) {
va_list va;
va_start (va, nargs);
for (int i=0; i<nargs; ++i) {
cb->arg[N+i] = va_arg(va, void*);
}
va_end (va);
}
}
EXPORTDYN
uint32_t RunFunctionWithEmu(x86emu_t *emu, int QuitOnLongJump, uintptr_t fnc, int nargs, ...)
{
+1 -1
View File
@@ -78,7 +78,7 @@ int FileIsX86ELF(const char* filename)
return 0;
}
#ifdef RPI
#if defined(RPI) || defined(RK3399)
void sanitize_mojosetup_gtk_background()
{
// get GTK2_RC_FILES folder
+530 -237
View File
@@ -14,14 +14,17 @@
#include "librarian.h"
#include "gtkclass.h"
#include "library.h"
#include "khash.h"
static bridge_t* my_bridge = NULL;
static int my_gobject = -1;
static int my_gtkobject = -1;
static int my_gtkwidget = -1;
static int my_gtkcontainer = -1;
static const char* (*g_type_name)(int) = NULL;
#define GTKCLASS(A) static int my_##A = -1;
GTKCLASSES()
#undef GTKCLASS
KHASH_SET_INIT_INT(signalmap)
static kh_signalmap_t *my_signalmap = NULL;
// ---- Defining the multiple functions now -----
#define SUPER() \
GO(0) \
@@ -41,51 +44,83 @@ static RET my_##NAME##_##A DEF \
return (RET)RunFunction(my_context, my_##NAME##_fct_##A, N, __VA_ARGS__);\
}
#define FIND(NAME) \
static void* find_##NAME(void* fct) \
{ \
if(!fct) return fct; \
if(my_##NAME##_fct_0 == (uintptr_t)fct) return my_##NAME##_0; \
if(my_##NAME##_fct_1 == (uintptr_t)fct) return my_##NAME##_1; \
if(my_##NAME##_fct_2 == (uintptr_t)fct) return my_##NAME##_2; \
if(my_##NAME##_fct_3 == (uintptr_t)fct) return my_##NAME##_3; \
if(my_##NAME##_fct_4 == (uintptr_t)fct) return my_##NAME##_4; \
if(my_##NAME##_fct_5 == (uintptr_t)fct) return my_##NAME##_5; \
if(my_##NAME##_fct_6 == (uintptr_t)fct) return my_##NAME##_6; \
if(my_##NAME##_fct_7 == (uintptr_t)fct) return my_##NAME##_7; \
if(my_##NAME##_fct_0 == 0) {my_##NAME##_fct_0 = (uintptr_t)fct; return my_##NAME##_0; } \
if(my_##NAME##_fct_1 == 0) {my_##NAME##_fct_1 = (uintptr_t)fct; return my_##NAME##_1; } \
if(my_##NAME##_fct_2 == 0) {my_##NAME##_fct_2 = (uintptr_t)fct; return my_##NAME##_2; } \
if(my_##NAME##_fct_3 == 0) {my_##NAME##_fct_3 = (uintptr_t)fct; return my_##NAME##_3; } \
if(my_##NAME##_fct_4 == 0) {my_##NAME##_fct_4 = (uintptr_t)fct; return my_##NAME##_4; } \
if(my_##NAME##_fct_5 == 0) {my_##NAME##_fct_5 = (uintptr_t)fct; return my_##NAME##_5; } \
if(my_##NAME##_fct_6 == 0) {my_##NAME##_fct_6 = (uintptr_t)fct; return my_##NAME##_6; } \
if(my_##NAME##_fct_7 == 0) {my_##NAME##_fct_7 = (uintptr_t)fct; return my_##NAME##_7; } \
#define FIND(A, NAME) \
static void* find_##NAME##_##A(void* fct) \
{ \
if(!fct) return fct; \
void* tmp = GetNativeFnc((uintptr_t)fct); \
if(tmp) return tmp; \
if(my_##NAME##_##A##_fct_0 == (uintptr_t)fct) return my_##NAME##_##A##_0; \
if(my_##NAME##_##A##_fct_1 == (uintptr_t)fct) return my_##NAME##_##A##_1; \
if(my_##NAME##_##A##_fct_2 == (uintptr_t)fct) return my_##NAME##_##A##_2; \
if(my_##NAME##_##A##_fct_3 == (uintptr_t)fct) return my_##NAME##_##A##_3; \
if(my_##NAME##_##A##_fct_4 == (uintptr_t)fct) return my_##NAME##_##A##_4; \
if(my_##NAME##_##A##_fct_5 == (uintptr_t)fct) return my_##NAME##_##A##_5; \
if(my_##NAME##_##A##_fct_6 == (uintptr_t)fct) return my_##NAME##_##A##_6; \
if(my_##NAME##_##A##_fct_7 == (uintptr_t)fct) return my_##NAME##_##A##_7; \
if(my_##NAME##_##A##_fct_0 == 0) {my_##NAME##_##A##_fct_0 = (uintptr_t)fct; return my_##NAME##_##A##_0; } \
if(my_##NAME##_##A##_fct_1 == 0) {my_##NAME##_##A##_fct_1 = (uintptr_t)fct; return my_##NAME##_##A##_1; } \
if(my_##NAME##_##A##_fct_2 == 0) {my_##NAME##_##A##_fct_2 = (uintptr_t)fct; return my_##NAME##_##A##_2; } \
if(my_##NAME##_##A##_fct_3 == 0) {my_##NAME##_##A##_fct_3 = (uintptr_t)fct; return my_##NAME##_##A##_3; } \
if(my_##NAME##_##A##_fct_4 == 0) {my_##NAME##_##A##_fct_4 = (uintptr_t)fct; return my_##NAME##_##A##_4; } \
if(my_##NAME##_##A##_fct_5 == 0) {my_##NAME##_##A##_fct_5 = (uintptr_t)fct; return my_##NAME##_##A##_5; } \
if(my_##NAME##_##A##_fct_6 == 0) {my_##NAME##_##A##_fct_6 = (uintptr_t)fct; return my_##NAME##_##A##_6; } \
if(my_##NAME##_##A##_fct_7 == 0) {my_##NAME##_##A##_fct_7 = (uintptr_t)fct; return my_##NAME##_##A##_7; } \
printf_log(LOG_NONE, "Warning, no more slot for " #NAME " gtkclass callback\n"); \
return NULL; \
}
#define WRAPPER(A, NAME, RET, DEF, N, ...) \
WRAPPED(0, NAME, RET, DEF, N, __VA_ARGS__) \
WRAPPED(1, NAME, RET, DEF, N, __VA_ARGS__) \
WRAPPED(2, NAME, RET, DEF, N, __VA_ARGS__) \
WRAPPED(3, NAME, RET, DEF, N, __VA_ARGS__) \
WRAPPED(4, NAME, RET, DEF, N, __VA_ARGS__) \
WRAPPED(5, NAME, RET, DEF, N, __VA_ARGS__) \
WRAPPED(6, NAME, RET, DEF, N, __VA_ARGS__) \
WRAPPED(7, NAME, RET, DEF, N, __VA_ARGS__) \
FIND(NAME)
#define REVERSE(A, NAME) \
static void* reverse_##NAME##_##A(wrapper_t W, void* fct) \
{ \
if(!fct) return fct; \
if((void*)my_##NAME##_##A##_0 == fct) return (void*)my_##NAME##_##A##_fct_0;\
if((void*)my_##NAME##_##A##_1 == fct) return (void*)my_##NAME##_##A##_fct_1;\
if((void*)my_##NAME##_##A##_2 == fct) return (void*)my_##NAME##_##A##_fct_2;\
if((void*)my_##NAME##_##A##_3 == fct) return (void*)my_##NAME##_##A##_fct_3;\
if((void*)my_##NAME##_##A##_4 == fct) return (void*)my_##NAME##_##A##_fct_4;\
if((void*)my_##NAME##_##A##_5 == fct) return (void*)my_##NAME##_##A##_fct_5;\
if((void*)my_##NAME##_##A##_6 == fct) return (void*)my_##NAME##_##A##_fct_6;\
if((void*)my_##NAME##_##A##_7 == fct) return (void*)my_##NAME##_##A##_fct_7;\
Dl_info info; \
if(dladdr(fct, &info)) \
return (void*)AddCheckBridge(my_bridge, my_context, W, fct, 0); \
return fct; \
}
#define AUTOBRIDGE(A, NAME) \
static void autobridge_##NAME##_##A(wrapper_t W, void* fct) \
{ \
if(!fct) \
return; \
Dl_info info; \
if(dladdr(fct, &info)) \
AddAutomaticBridge(thread_get_emu(), my_bridge, W, fct, 0); \
}
#define WRAPPER(A, NAME, RET, DEF, N, ...) \
WRAPPED(0, NAME##_##A, RET, DEF, N, __VA_ARGS__) \
WRAPPED(1, NAME##_##A, RET, DEF, N, __VA_ARGS__) \
WRAPPED(2, NAME##_##A, RET, DEF, N, __VA_ARGS__) \
WRAPPED(3, NAME##_##A, RET, DEF, N, __VA_ARGS__) \
WRAPPED(4, NAME##_##A, RET, DEF, N, __VA_ARGS__) \
WRAPPED(5, NAME##_##A, RET, DEF, N, __VA_ARGS__) \
WRAPPED(6, NAME##_##A, RET, DEF, N, __VA_ARGS__) \
WRAPPED(7, NAME##_##A, RET, DEF, N, __VA_ARGS__) \
FIND(A, NAME) \
REVERSE(A, NAME) \
AUTOBRIDGE(A, NAME)
// ----- GObjectClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(A, constructor, void*, (int type, uint32_t n_construct_properties, void* construct_properties), 3, type, n_construct_properties, construct_properties);
WRAPPER(A, set_property, void, (void* object, uint32_t property_id, void* value, void* pspec), 4, object, property_id, value, pspec);
WRAPPER(A, get_property, void, (void* object, uint32_t property_id, void* value, void* pspec), 4, object, property_id, value, pspec);
WRAPPER(A, dispose, void, (void* object), 1, object);
WRAPPER(A, finalize, void, (void* object), 1, object);
WRAPPER(A, dispatch_properties_changed, void*, (int type, uint32_t n_pspecs, void* pspecs), 3, type, n_pspecs, pspecs);
WRAPPER(A, notify, void*, (int type, void* pspecs), 2, type, pspecs);
WRAPPER(A, constructed, void, (void* object), 1, object);
WRAPPER(GObject, constructor, void*, (int type, uint32_t n_construct_properties, void* construct_properties), 3, type, n_construct_properties, construct_properties);
WRAPPER(GObject, set_property, void, (void* object, uint32_t property_id, void* value, void* pspec), 4, object, property_id, value, pspec);
WRAPPER(GObject, get_property, void, (void* object, uint32_t property_id, void* value, void* pspec), 4, object, property_id, value, pspec);
WRAPPER(GObject, dispose, void, (void* object), 1, object);
WRAPPER(GObject, finalize, void, (void* object), 1, object);
WRAPPER(GObject, dispatch_properties_changed, void*, (int type, uint32_t n_pspecs, void* pspecs), 3, type, n_pspecs, pspecs);
WRAPPER(GObject, notify, void*, (int type, void* pspecs), 2, type, pspecs);
WRAPPER(GObject, constructed, void, (void* object), 1, object);
#define SUPERGO() \
GO(constructor, pFiup); \
@@ -100,15 +135,21 @@ WRAPPER(A, constructed, void, (void* object), 1, object);
// wrap (so bridge all calls, just in case)
static void wrapGObjectClass(my_GObjectClass_t* class)
{
#define GO(A, W) if(class->A) class->A = (void*)AddCheckBridge(my_bridge, W, class->A, 0)
#define GO(A, W) class->A = reverse_##A##_GObject (W, class->A)
SUPERGO()
#undef GO
}
// unwrap (and use callback if not a native call anymore)
static void unwrapGObjectClass(my_GObjectClass_t* class)
{
void* tmp;
#define GO(A, W) if(class->A) {tmp = GetNativeFnc((uintptr_t)class->A); if(tmp) class->A = tmp; else class->A = find_##A (class->A);}
#define GO(A, W) class->A = find_##A##_GObject (class->A)
SUPERGO()
#undef GO
}
// autobridge
static void bridgeGObjectClass(my_GObjectClass_t* class)
{
#define GO(A, W) autobridge_##A##_GObject (W, class->A)
SUPERGO()
#undef GO
}
@@ -116,9 +157,9 @@ static void unwrapGObjectClass(my_GObjectClass_t* class)
// ----- GtkObjectClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(A, set_arg, void, (void* object, void* arg, uint32_t arg_id), 3, object, arg, arg_id);
WRAPPER(A, get_arg, void, (void* object, void* arg, uint32_t arg_id), 3, object, arg, arg_id);
WRAPPER(A, destroy, void, (void* object), 1, object);
WRAPPER(GtkObject, set_arg, void, (void* object, void* arg, uint32_t arg_id), 3, object, arg, arg_id);
WRAPPER(GtkObject, get_arg, void, (void* object, void* arg, uint32_t arg_id), 3, object, arg, arg_id);
WRAPPER(GtkObject, destroy, void, (void* object), 1, object);
#define SUPERGO() \
GO(set_arg, vFppu); \
@@ -128,7 +169,7 @@ WRAPPER(A, destroy, void, (void* object), 1, object);
static void wrapGtkObjectClass(my_GtkObjectClass_t* class)
{
wrapGObjectClass(&class->parent_class);
#define GO(A, W) if(class->A) class->A = (void*)AddCheckBridge(my_bridge, W, class->A, 0)
#define GO(A, W) class->A = reverse_##A##_GtkObject (W, class->A)
SUPERGO()
#undef GO
}
@@ -136,81 +177,89 @@ static void wrapGtkObjectClass(my_GtkObjectClass_t* class)
static void unwrapGtkObjectClass(my_GtkObjectClass_t* class)
{
unwrapGObjectClass(&class->parent_class);
void* tmp;
#define GO(A, W) if(class->A) {tmp = GetNativeFnc((uintptr_t)class->A); if(tmp) class->A = tmp; else class->A = find_##A (class->A);}
#define GO(A, W) class->A = find_##A##_GtkObject (class->A)
SUPERGO()
#undef GO
}
// autobridge
static void bridgeGtkObjectClass(my_GtkObjectClass_t* class)
{
bridgeGObjectClass(&class->parent_class);
#define GO(A, W) autobridge_##A##_GtkObject (W, class->A)
SUPERGO()
#undef GO
}
#undef SUPERGO
// ----- GtkWidgetClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(A, dispatch_child_properties_changed, void, (void* widget, uint32_t n_pspecs, void* pspecs), 3, widget, n_pspecs, pspecs);
WRAPPER(A, show, void, (void* widget), 1, widget);
WRAPPER(A, show_all, void, (void* widget), 1, widget);
WRAPPER(A, hide, void, (void* widget), 1, widget);
WRAPPER(A, hide_all, void, (void* widget), 1, widget);
WRAPPER(A, map, void, (void* widget), 1, widget);
WRAPPER(A, unmap, void, (void* widget), 1, widget);
WRAPPER(A, realize, void, (void* widget), 1, widget);
WRAPPER(A, unrealize, void, (void* widget), 1, widget);
WRAPPER(A, size_request, void, (void* widget, void* requisition), 2, widget, requisition);
WRAPPER(A, size_allocate, void, (void* widget, void* allocation), 2, widget, allocation);
WRAPPER(A, state_changed, void, (void* widget, int previous_state), 2, widget, previous_state);
WRAPPER(A, parent_set, void, (void* widget, void* previous_parent), 2, widget, previous_parent);
WRAPPER(A, hierarchy_changed, void, (void* widget, void* previous_toplevel), 2, widget, previous_toplevel);
WRAPPER(A, style_set, void, (void* widget, void* previous_style), 2, widget, previous_style);
WRAPPER(A, direction_changed, void, (void* widget, int previous_direction), 2, widget, previous_direction);
WRAPPER(A, grab_notify, void, (void* widget, int was_grabbed), 2, widget, was_grabbed);
WRAPPER(A, child_notify, void, (void* widget, void* pspec), 2, widget, pspec);
WRAPPER(A, mnemonic_activate, int, (void* widget, int group_cycling), 2, widget, group_cycling);
WRAPPER(A, grab_focus, void, (void* widget), 1, widget);
WRAPPER(A, focus, int, (void* widget, int direction), 2, widget, direction);
WRAPPER(A, event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, button_press_event,int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, button_release_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, scroll_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, motion_notify_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, delete_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, destroy_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, expose_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, key_press_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, key_release_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, enter_notify_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, leave_notify_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, configure_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, focus_in_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, focus_out_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, map_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, unmap_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, property_notify_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, selection_clear_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, selection_request_event,int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, selection_notify_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, proximity_in_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, proximity_out_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, visibility_notify_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, client_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, no_expose_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, window_state_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(A, selection_get, void, (void* widget, void* selection_data, uint32_t info, uint32_t time_), 4, widget, selection_data, info, time_);
WRAPPER(A, selection_received, void, (void* widget, void* selection_data, uint32_t time_), 3, widget, selection_data, time_);
WRAPPER(A, drag_begin, void, (void* widget, void* context), 2, widget, context);
WRAPPER(A, drag_end, void, (void* widget, void* context), 2, widget, context);
WRAPPER(A, drag_data_get, void, (void* widget, void* context, void* selection_data, uint32_t info, uint32_t time_), 5, widget, context, selection_data, info, time_);
WRAPPER(A, drag_data_delete, void, (void* widget, void* context), 2, widget, context);
WRAPPER(A, drag_leave, void, (void* widget, void* context, uint32_t time_), 3, widget, context, time_);
WRAPPER(A, drag_motion, int, (void* widget, void* context, int32_t x, int32_t y, uint32_t time_), 5, widget, context, x, y, time_);
WRAPPER(A, drag_drop, int, (void* widget, void* context, int32_t x, int32_t y, uint32_t time_), 5, widget, context, x, y, time_);
WRAPPER(A, drag_data_received, void, (void* widget, void* context, int32_t x, int32_t y, void* selection_data, uint32_t info, uint32_t time_), 7, widget, context, x, y, selection_data, info, time_);
WRAPPER(A, popup_menu, int , (void* widget), 1, widget);
WRAPPER(A, show_help, int , (void* widget, int help_type), 2, widget, help_type);
WRAPPER(A, get_accessible, void*, (void* widget), 1, widget);
WRAPPER(A, screen_changed, void , (void* widget, void* previous_screen), 2, widget, previous_screen);
WRAPPER(A, can_activate_accel, int , (void* widget, uint32_t signal_id), 2, widget, signal_id);
WRAPPER(A, grab_broken_event, int , (void* widget, void* event), 2, widget, event);
WRAPPER(A, composited_changed, void , (void* widget), 1, widget);
WRAPPER(A, query_tooltip, int , (void* widget, int32_t x, int32_t y, int keyboard_tooltip, void* tooltip), 5, widget, x, y, keyboard_tooltip, tooltip);
WRAPPER(GtkWidget, dispatch_child_properties_changed, void, (void* widget, uint32_t n_pspecs, void* pspecs), 3, widget, n_pspecs, pspecs);
WRAPPER(GtkWidget, show, void, (void* widget), 1, widget);
WRAPPER(GtkWidget, show_all, void, (void* widget), 1, widget);
WRAPPER(GtkWidget, hide, void, (void* widget), 1, widget);
WRAPPER(GtkWidget, hide_all, void, (void* widget), 1, widget);
WRAPPER(GtkWidget, map, void, (void* widget), 1, widget);
WRAPPER(GtkWidget, unmap, void, (void* widget), 1, widget);
WRAPPER(GtkWidget, realize, void, (void* widget), 1, widget);
WRAPPER(GtkWidget, unrealize, void, (void* widget), 1, widget);
WRAPPER(GtkWidget, size_request, void, (void* widget, void* requisition), 2, widget, requisition);
WRAPPER(GtkWidget, size_allocate, void, (void* widget, void* allocation), 2, widget, allocation);
WRAPPER(GtkWidget, state_changed, void, (void* widget, int previous_state), 2, widget, previous_state);
WRAPPER(GtkWidget, parent_set, void, (void* widget, void* previous_parent), 2, widget, previous_parent);
WRAPPER(GtkWidget, hierarchy_changed, void, (void* widget, void* previous_toplevel), 2, widget, previous_toplevel);
WRAPPER(GtkWidget, style_set, void, (void* widget, void* previous_style), 2, widget, previous_style);
WRAPPER(GtkWidget, direction_changed, void, (void* widget, int previous_direction), 2, widget, previous_direction);
WRAPPER(GtkWidget, grab_notify, void, (void* widget, int was_grabbed), 2, widget, was_grabbed);
WRAPPER(GtkWidget, child_notify, void, (void* widget, void* pspec), 2, widget, pspec);
WRAPPER(GtkWidget, mnemonic_activate, int, (void* widget, int group_cycling), 2, widget, group_cycling);
WRAPPER(GtkWidget, grab_focus, void, (void* widget), 1, widget);
WRAPPER(GtkWidget, focus, int, (void* widget, int direction), 2, widget, direction);
WRAPPER(GtkWidget, event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, button_press_event,int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, button_release_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, scroll_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, motion_notify_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, delete_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, destroy_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, expose_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, key_press_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, key_release_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, enter_notify_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, leave_notify_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, configure_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, focus_in_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, focus_out_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, map_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, unmap_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, property_notify_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, selection_clear_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, selection_request_event,int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, selection_notify_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, proximity_in_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, proximity_out_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, visibility_notify_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, client_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, no_expose_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, window_state_event, int, (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, selection_get, void, (void* widget, void* selection_data, uint32_t info, uint32_t time_), 4, widget, selection_data, info, time_);
WRAPPER(GtkWidget, selection_received, void, (void* widget, void* selection_data, uint32_t time_), 3, widget, selection_data, time_);
WRAPPER(GtkWidget, drag_begin, void, (void* widget, void* context), 2, widget, context);
WRAPPER(GtkWidget, drag_end, void, (void* widget, void* context), 2, widget, context);
WRAPPER(GtkWidget, drag_data_get, void, (void* widget, void* context, void* selection_data, uint32_t info, uint32_t time_), 5, widget, context, selection_data, info, time_);
WRAPPER(GtkWidget, drag_data_delete, void, (void* widget, void* context), 2, widget, context);
WRAPPER(GtkWidget, drag_leave, void, (void* widget, void* context, uint32_t time_), 3, widget, context, time_);
WRAPPER(GtkWidget, drag_motion, int, (void* widget, void* context, int32_t x, int32_t y, uint32_t time_), 5, widget, context, x, y, time_);
WRAPPER(GtkWidget, drag_drop, int, (void* widget, void* context, int32_t x, int32_t y, uint32_t time_), 5, widget, context, x, y, time_);
WRAPPER(GtkWidget, drag_data_received, void, (void* widget, void* context, int32_t x, int32_t y, void* selection_data, uint32_t info, uint32_t time_), 7, widget, context, x, y, selection_data, info, time_);
WRAPPER(GtkWidget, popup_menu, int , (void* widget), 1, widget);
WRAPPER(GtkWidget, show_help, int , (void* widget, int help_type), 2, widget, help_type);
WRAPPER(GtkWidget, get_accessible, void*, (void* widget), 1, widget);
WRAPPER(GtkWidget, screen_changed, void , (void* widget, void* previous_screen), 2, widget, previous_screen);
WRAPPER(GtkWidget, can_activate_accel, int , (void* widget, uint32_t signal_id), 2, widget, signal_id);
WRAPPER(GtkWidget, grab_broken_event, int , (void* widget, void* event), 2, widget, event);
WRAPPER(GtkWidget, composited_changed, void , (void* widget), 1, widget);
WRAPPER(GtkWidget, query_tooltip, int , (void* widget, int32_t x, int32_t y, int keyboard_tooltip, void* tooltip), 5, widget, x, y, keyboard_tooltip, tooltip);
#define SUPERGO() \
GO(dispatch_child_properties_changed, vFpup); \
@@ -284,7 +333,7 @@ WRAPPER(A, query_tooltip, int , (void* widget, int32_t x, int32_t y, int
static void wrapGtkWidgetClass(my_GtkWidgetClass_t* class)
{
wrapGtkObjectClass(&class->parent_class);
#define GO(A, W) if(class->A) class->A = (void*)AddCheckBridge(my_bridge, W, class->A, 0)
#define GO(A, W) class->A = reverse_##A##_GtkWidget (W, class->A)
SUPERGO()
#undef GO
}
@@ -292,24 +341,32 @@ static void wrapGtkWidgetClass(my_GtkWidgetClass_t* class)
static void unwrapGtkWidgetClass(my_GtkWidgetClass_t* class)
{
unwrapGtkObjectClass(&class->parent_class);
void* tmp;
#define GO(A, W) if(class->A) {tmp = GetNativeFnc((uintptr_t)class->A); if(tmp) class->A = tmp; else class->A = find_##A (class->A);}
#define GO(A, W) class->A = find_##A##_GtkWidget (class->A)
SUPERGO()
#undef GO
}
// autobridge
static void bridgeGtkWidgetClass(my_GtkWidgetClass_t* class)
{
bridgeGtkObjectClass(&class->parent_class);
#define GO(A, W) autobridge_##A##_GtkWidget (W, class->A)
SUPERGO()
#undef GO
}
#undef SUPERGO
// ----- GtkContainerClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(A, add, void, (void* container, void* widget), 2, container, widget);
WRAPPER(A, remove, void, (void* container, void* widget), 2, container, widget);
WRAPPER(A, check_resize, void, (void* container), 1, container);
WRAPPER(A, forall, void, (void* container, int include_internals, void* callback, void* callback_data), 4, container, include_internals, AddCheckBridge(my_bridge, vFpp, callback, 0), callback_data);
WRAPPER(A, set_focus_child, void, (void* container, void* widget), 2, container, widget);
WRAPPER(A, child_type, int, (void* container), 1, container);
WRAPPER(A, composite_name, void*, (void* container, void* child), 2, container, child);
WRAPPER(A, set_child_property, void, (void* container, void* child, uint32_t property_id, void* value, void* pspec), 5, container, child, property_id, value, pspec);
WRAPPER(A, get_child_property, void, (void* container, void* child, uint32_t property_id, void* value, void* pspec), 5, container, child, property_id, value, pspec);
WRAPPER(GtkContainer, add, void, (void* container, void* widget), 2, container, widget);
WRAPPER(GtkContainer, remove, void, (void* container, void* widget), 2, container, widget);
WRAPPER(GtkContainer, check_resize, void, (void* container), 1, container);
WRAPPER(GtkContainer, forall, void, (void* container, int include_internals, void* callback, void* callback_data), 4, container, include_internals, AddCheckBridge(my_bridge, my_context, vFpp, callback, 0), callback_data);
WRAPPER(GtkContainer, set_focus_child, void, (void* container, void* widget), 2, container, widget);
WRAPPER(GtkContainer, child_type, int, (void* container), 1, container);
WRAPPER(GtkContainer, composite_name, void*, (void* container, void* child), 2, container, child);
WRAPPER(GtkContainer, set_child_property, void, (void* container, void* child, uint32_t property_id, void* value, void* pspec), 5, container, child, property_id, value, pspec);
WRAPPER(GtkContainer, get_child_property, void, (void* container, void* child, uint32_t property_id, void* value, void* pspec), 5, container, child, property_id, value, pspec);
#define SUPERGO() \
GO(add, vFpp); \
@@ -326,7 +383,7 @@ WRAPPER(A, get_child_property, void, (void* container, void* child, uint32_t pro
static void wrapGtkContainerClass(my_GtkContainerClass_t* class)
{
wrapGtkWidgetClass(&class->parent_class);
#define GO(A, W) if(class->A) class->A = (void*)AddCheckBridge(my_bridge, W, class->A, 0)
#define GO(A, W) class->A = reverse_##A##_GtkContainer (W, class->A)
SUPERGO()
#undef GO
}
@@ -334,89 +391,306 @@ static void wrapGtkContainerClass(my_GtkContainerClass_t* class)
static void unwrapGtkContainerClass(my_GtkContainerClass_t* class)
{
unwrapGtkWidgetClass(&class->parent_class);
void* tmp;
#define GO(A, W) if(class->A) {tmp = GetNativeFnc((uintptr_t)class->A); if(tmp) class->A = tmp; else class->A = find_##A (class->A);}
#define GO(A, W) class->A = find_##A##_GtkContainer (class->A)
SUPERGO()
#undef GO
}
// autobridge
static void bridgeGtkContainerClass(my_GtkContainerClass_t* class)
{
bridgeGtkWidgetClass(&class->parent_class);
#define GO(A, W) autobridge_##A##_GtkContainer (W, class->A)
SUPERGO()
#undef GO
}
#undef SUPERGO
// ----- GtkActionClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkAction, activate, void, (void* action), 1, action);
WRAPPER(GtkAction, create_menu_item, void*, (void* action), 1, action);
WRAPPER(GtkAction, create_tool_item, void*, (void* action), 1, action);
WRAPPER(GtkAction, connect_proxy, void , (void* action, void* proxy), 2, action, proxy);
WRAPPER(GtkAction, disconnect_proxy, void , (void* action, void* proxy), 2, action, proxy);
WRAPPER(GtkAction, create_menu, void*, (void* action), 1, action);
#define SUPERGO() \
GO(activate, vFp); \
GO(create_menu_item, pFp); \
GO(create_tool_item, pFp); \
GO(connect_proxy, vFpp); \
GO(disconnect_proxy, vFpp); \
GO(create_menu, pFp); \
// wrap (so bridge all calls, just in case)
static void wrapGtkActionClass(my_GtkActionClass_t* class)
{
wrapGObjectClass(&class->parent_class);
#define GO(A, W) class->A = reverse_##A##_GtkAction (W, class->A)
SUPERGO()
#undef GO
}
// unwrap (and use callback if not a native call anymore)
static void unwrapGtkActionClass(my_GtkActionClass_t* class)
{
unwrapGObjectClass(&class->parent_class);
#define GO(A, W) class->A = find_##A##_GtkAction (class->A)
SUPERGO()
#undef GO
}
// autobridge
static void bridgeGtkActionClass(my_GtkActionClass_t* class)
{
bridgeGObjectClass(&class->parent_class);
#define GO(A, W) autobridge_##A##_GtkAction (W, class->A)
SUPERGO()
#undef GO
}
#undef SUPERGO
// ----- GtkMiscClass ------
// wrap (so bridge all calls, just in case)
static void wrapGtkMiscClass(my_GtkMiscClass_t* class)
{
wrapGtkWidgetClass(&class->parent_class);
}
// unwrap (and use callback if not a native call anymore)
static void unwrapGtkMiscClass(my_GtkMiscClass_t* class)
{
unwrapGtkWidgetClass(&class->parent_class);
}
// autobridge
static void bridgeGtkMiscClass(my_GtkMiscClass_t* class)
{
bridgeGtkWidgetClass(&class->parent_class);
}
// ----- GtkLabelClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkMisc, move_cursor, void, (void* label, int step, int count, int extend_selection), 4, label, step, count, extend_selection);
WRAPPER(GtkMisc, copy_clipboard, void, (void* label), 1, label);
WRAPPER(GtkMisc, populate_popup, void, (void* label, void* menu), 2, label, menu);
WRAPPER(GtkMisc, activate_link, int, (void* label, void* uri), 2, label, uri);
#define SUPERGO() \
GO(move_cursor, vFpiii); \
GO(copy_clipboard, vFp); \
GO(populate_popup, vFpp); \
GO(activate_link, iFpp); \
// wrap (so bridge all calls, just in case)
static void wrapGtkLabelClass(my_GtkLabelClass_t* class)
{
wrapGtkMiscClass(&class->parent_class);
#define GO(A, W) class->A = reverse_##A##_GtkMisc (W, class->A)
SUPERGO()
#undef GO
}
// unwrap (and use callback if not a native call anymore)
static void unwrapGtkLabelClass(my_GtkLabelClass_t* class)
{
unwrapGtkMiscClass(&class->parent_class);
#define GO(A, W) class->A = find_##A##_GtkMisc (class->A)
SUPERGO()
#undef GO
}
// autobridge
static void bridgeGtkLabelClass(my_GtkLabelClass_t* class)
{
bridgeGtkMiscClass(&class->parent_class);
#define GO(A, W) autobridge_##A##_GtkMisc (W, class->A)
SUPERGO()
#undef GO
}
#undef SUPERGO
// ----- GtkTreeViewClass ------
// wrapper x86 -> natives of callbacks
WRAPPER(GtkTreeView, set_scroll_adjustments, void, (void* tree_view, void* hadjustment, void* vadjustment), 3, tree_view, hadjustment, vadjustment);
WRAPPER(GtkTreeView, row_activated, void, (void* tree_view, void* path, void* column), 3, tree_view, path, column);
WRAPPER(GtkTreeView, test_expand_row, int, (void* tree_view, void* iter, void* path), 3, tree_view, iter, path);
WRAPPER(GtkTreeView, test_collapse_row, int, (void* tree_view, void* iter, void* path), 3, tree_view, iter, path);
WRAPPER(GtkTreeView, row_expanded, void, (void* tree_view, void* iter, void* path), 3, tree_view, iter, path);
WRAPPER(GtkTreeView, row_collapsed, void, (void* tree_view, void* iter, void* path), 3, tree_view, iter, path);
WRAPPER(GtkTreeView, columns_changed, void, (void* tree_view), 1, tree_view);
WRAPPER(GtkTreeView, cursor_changed, void, (void* tree_view), 1, tree_view);
WRAPPER(GtkTreeView, move_cursor, int, (void* tree_view, int step, int count), 3, tree_view, step, count);
WRAPPER(GtkTreeView, select_all, int, (void* tree_view), 1, tree_view);
WRAPPER(GtkTreeView, unselect_all, int, (void* tree_view), 1, tree_view);
WRAPPER(GtkTreeView, select_cursor_row, int, (void* tree_view, int start_editing), 2, tree_view, start_editing);
WRAPPER(GtkTreeView, toggle_cursor_row, int, (void* tree_view), 1, tree_view);
WRAPPER(GtkTreeView, expand_collapse_cursor_row, int, (void* tree_view, int logical, int expand, int open_all), 4, tree_view, logical, expand, open_all);
WRAPPER(GtkTreeView, select_cursor_parent, int, (void* tree_view), 1, tree_view);
WRAPPER(GtkTreeView, start_interactive_search, int, (void* tree_view), 1, tree_view);
#define SUPERGO() \
GO(set_scroll_adjustments, vFppp); \
GO(row_activated, vFppp); \
GO(test_expand_row, iFppp); \
GO(test_collapse_row, iFppp); \
GO(row_expanded, vFppp); \
GO(row_collapsed, vFppp); \
GO(columns_changed, vFp); \
GO(cursor_changed, vFp); \
GO(move_cursor, iFppp); \
GO(select_all, iFp); \
GO(unselect_all, iFp); \
GO(select_cursor_row, iFpi); \
GO(toggle_cursor_row, iFp); \
GO(expand_collapse_cursor_row, iFpiii); \
GO(select_cursor_parent, iFp); \
GO(start_interactive_search, iFp); \
// wrap (so bridge all calls, just in case)
static void wrapGtkTreeViewClass(my_GtkTreeViewClass_t* class)
{
wrapGtkContainerClass(&class->parent_class);
#define GO(A, W) class->A = reverse_##A##_GtkTreeView (W, class->A)
SUPERGO()
#undef GO
}
// unwrap (and use callback if not a native call anymore)
static void unwrapGtkTreeViewClass(my_GtkTreeViewClass_t* class)
{
unwrapGtkContainerClass(&class->parent_class);
#define GO(A, W) class->A = find_##A##_GtkTreeView (class->A)
SUPERGO()
#undef GO
}
// autobridge
static void bridgeGtkTreeViewClass(my_GtkTreeViewClass_t* class)
{
bridgeGtkContainerClass(&class->parent_class);
#define GO(A, W) autobridge_##A##_GtkTreeView (W, class->A)
SUPERGO()
#undef GO
}
#undef SUPERGO
// No more wrap/unwrap
#undef WRAPPER
#undef FIND
#undef REVERSE
#undef WRAPPED
static void wrapGTKClass(void* class, int type)
// g_type_class_peek_parent
static void wrapGTKClass(void* cl, int type)
{
if(type==my_gtkcontainer)
wrapGtkContainerClass((my_GtkContainerClass_t*)class);
else if(type==my_gtkwidget)
wrapGtkWidgetClass((my_GtkWidgetClass_t*)class);
else if(type==my_gtkobject)
wrapGtkObjectClass((my_GtkObjectClass_t*)class);
else if(type==my_gobject)
wrapGObjectClass((my_GObjectClass_t*)class);
else {
printf_log(LOG_INFO, "Warning, Custom Class initializer with unknown class type %d (%s)\n", type, g_type_name(type));
#define GTKCLASS(A) \
if(type==my_##A) \
wrap##A##Class((my_##A##Class_t*)cl); \
else
GTKCLASSES()
{
printf_log(LOG_NONE, "Warning, Custom Class initializer with unknown class type %d (%s)\n", type, g_type_name(type));
}
#undef GTKCLASS
}
static void unwrapGTKClass(void* class, int type)
static void unwrapGTKClass(void* cl, int type)
{
if(type==my_gtkcontainer)
unwrapGtkContainerClass((my_GtkContainerClass_t*)class);
else if(type==my_gtkwidget)
unwrapGtkWidgetClass((my_GtkWidgetClass_t*)class);
else if(type==my_gtkobject)
unwrapGtkObjectClass((my_GtkObjectClass_t*)class);
else if(type==my_gobject)
unwrapGObjectClass((my_GObjectClass_t*)class);
// no warning, one is enough...
#define GTKCLASS(A) \
if(type==my_##A) \
unwrap##A##Class((my_##A##Class_t*)cl); \
else
GTKCLASSES()
{} // else no warning, one is enough...
#undef GTKCLASS
}
// ---- GTKClass -----
static void** table_ref = NULL;
static void** table_nat = NULL;
static int table_sz = 0;
static int table_cap = 0;
void* wrapCopyGTKClass(void* class, int type)
static void bridgeGTKClass(void* cl, int type)
{
// search for an existing ref...
for (int i=0; i<table_sz; ++i)
if(table_ref[i] == class)
return table_nat[i];
// add a new one...
if(table_sz == table_cap) {
table_cap += 4;
table_ref = (void**)realloc(table_ref, sizeof(void*)*table_cap);
table_nat = (void**)realloc(table_nat, sizeof(void*)*table_cap);
#define GTKCLASS(A) \
if(type==my_##A) \
bridge##A##Class((my_##A##Class_t*)cl); \
else
GTKCLASSES()
{
printf_log(LOG_NONE, "Warning, AutoBridge GTK Class with unknown class type %d (%s)\n", type, g_type_name(type));
}
table_ref[table_sz] = class;
if(type==my_gtkcontainer) {
my_GtkContainerClass_t *tmp = (my_GtkContainerClass_t*)malloc(sizeof(my_GtkContainerClass_t));
memcpy(tmp, class, sizeof(my_GtkContainerClass_t));
wrapGtkContainerClass(tmp);
table_nat[table_sz] = tmp;
} else if(type==my_gtkwidget) {
my_GtkWidgetClass_t *tmp = (my_GtkWidgetClass_t*)malloc(sizeof(my_GtkWidgetClass_t));
memcpy(tmp, class, sizeof(my_GtkWidgetClass_t));
wrapGtkWidgetClass(tmp);
table_nat[table_sz] = tmp;
} else if(type==my_gtkobject) {
my_GtkObjectClass_t *tmp = (my_GtkObjectClass_t*)malloc(sizeof(my_GtkObjectClass_t));
memcpy(tmp, class, sizeof(my_GtkObjectClass_t));
wrapGtkObjectClass((my_GtkObjectClass_t*)class);
table_nat[table_sz] = tmp;
} else if(type==my_gobject) {
my_GObjectClass_t *tmp = (my_GObjectClass_t*)malloc(sizeof(my_GObjectClass_t));
memcpy(tmp, class, sizeof(my_GObjectClass_t));
wrapGObjectClass((my_GObjectClass_t*)class);
table_nat[table_sz] = tmp;
} else {
printf_log(LOG_INFO, "Warning, Custom Class function with unknown class type %d (%s)\n", type, g_type_name(type));
return class;
#undef GTKCLASS
}
typedef union my_GClassAll_s {
#define GTKCLASS(A) my_##A##Class_t A;
GTKCLASSES()
#undef GTKCLASS
} my_GClassAll_t;
#define GO(A) \
static void* my_gclassall_ref_##A = NULL; \
static my_GClassAll_t my_gclassall_##A;
SUPER()
#undef GO
void* unwrapCopyGTKClass(void* klass, int type)
{
if(!klass) return klass;
#define GO(A) if(klass == my_gclassall_ref_##A) return &my_gclassall_##A;
SUPER()
#undef GO
// check if class is the exact type we know
int sz = 0;
#define GTKCLASS(A) if(type==my_##A) sz = sizeof(my_##A##Class_t); else
GTKCLASSES()
{
printf_log(LOG_NONE, "Warning, unwrapCopyGTKClass called with unknown class type %d (%s)\n", type, g_type_name(type));
return klass;
}
return table_nat[table_sz++];
#undef GTKCLASS
my_GClassAll_t *newklass = NULL;
#define GO(A) if(!newklass && !my_gclassall_ref_##A) {my_gclassall_ref_##A = klass; newklass = &my_gclassall_##A;}
SUPER()
#undef GO
if(!newklass) {
printf_log(LOG_NONE, "Warning: no more slot for unwrapCopyGTKClass\n");
return klass;
}
memcpy(newklass, klass, sz);
unwrapGTKClass(newklass, type);
return newklass;
}
// gtk_type_class
#define GO(A) \
static void* my_gclassallu_ref_##A = NULL; \
static my_GClassAll_t my_gclassallu_##A;
SUPER()
#undef GO
void* wrapCopyGTKClass(void* klass, int type)
{
if(!klass) return klass;
#define GO(A) if(klass == my_gclassallu_ref_##A) return &my_gclassallu_##A;
SUPER()
#undef GO
// check if class is the exact type we know
int sz = 0;
#define GTKCLASS(A) if(type==my_##A) sz = sizeof(my_##A##Class_t); else
GTKCLASSES()
{
printf_log(LOG_NONE, "Warning, wrapCopyGTKClass called with unknown class type 0x%x (%s)\n", type, g_type_name(type));
return klass;
}
#undef GTKCLASS
my_GClassAll_t *newklass = NULL;
#define GO(A) if(!newklass && !my_gclassallu_ref_##A) {my_gclassallu_ref_##A = klass; newklass = &my_gclassallu_##A;}
SUPER()
#undef GO
if(!newklass) {
printf_log(LOG_NONE, "Warning: no more slot for wrapCopyGTKClass\n");
return klass;
}
memcpy(newklass, klass, sz);
wrapGTKClass(newklass, type);
return newklass;
}
// ---- GTypeValueTable ----
@@ -636,38 +910,41 @@ my_GtkTypeInfo_t* findFreeGtkTypeInfo(my_GtkTypeInfo_t* fcts, int parent)
void InitGTKClass(bridge_t *bridge)
{
my_bridge = bridge;
my_signalmap = kh_init(signalmap);
}
void FiniGTKClass()
{
if(table_ref)
free(table_ref);
for (int i=0; i<table_sz; ++i)
free(table_nat[i]);
if(table_nat)
free(table_nat);
table_ref = table_nat = NULL;
table_sz = table_cap = 0;
if(my_signalmap) {
/*khint_t k;
kh_foreach_key(my_signalmap, k,
my_signal_t* p = (my_signal_t*)(uintptr_t)k;
free(p);
);*/ // lets assume all signals data is freed by gtk already
kh_destroy(signalmap, my_signalmap);
my_signalmap = NULL;
}
}
void SetGObjectID(int id)
{
my_gobject = id;
#define GTKCLASS(A) \
void Set##A##ID(int id) \
{ \
my_##A = id; \
}
GTKCLASSES()
#undef GTKCLASS
void SetGTKObjectID(int id)
void AutoBridgeGtk(void*(*ref)(int), void(*unref)(void*))
{
my_gtkobject = id;
}
void SetGTKWidgetID(int id)
{
my_gtkwidget = id;
}
void SetGTKContainerID(int id)
{
my_gtkcontainer = id;
void* p;
#define GTKCLASS(A) \
if(my_##A && my_##A!=-1) { \
p = ref(my_##A); \
bridgeGTKClass(p, my_##A); \
unref(p); \
}
GTKCLASSES()
#undef GTKCLASS
}
void SetGTypeName(void* f)
@@ -722,10 +999,18 @@ my_signal_t* new_mysignal(void* f, void* data, void* destroy)
sig->c_handler = (uintptr_t)f;
sig->destroy = (uintptr_t)destroy;
sig->data = data;
int ret;
kh_put(signalmap, my_signalmap, (uintptr_t)sig, &ret);
return sig;
}
void my_signal_delete(my_signal_t* sig)
{
khint_t k = kh_get(signalmap, my_signalmap, (uintptr_t)sig);
if(k!=kh_end(my_signalmap)) {
kh_del(signalmap, my_signalmap, k);
} else {
printf_log(LOG_NONE, "Warning, my_signal_delete called with an unrefereced signal!\n");
}
uintptr_t d = sig->destroy;
if(d) {
RunFunction(my_context, d, 1, sig->data);
@@ -733,6 +1018,18 @@ void my_signal_delete(my_signal_t* sig)
printf_log(LOG_DEBUG, "gtk Data deleted, sig=%p, data=%p, destroy=%p\n", sig, sig->data, (void*)d);
free(sig);
}
int my_signal_is_valid(void* sig)
{
khint_t k = kh_get(signalmap, my_signalmap, (uintptr_t)sig);
if(k!=kh_end(my_signalmap)) {
/*if(((my_signal_t*)c)->sign == SIGN)
return 1;
else
printf_log(LOG_NONE, "Warning, incohrent my_signal_t structure referenced\n");*/
return 1;
}
return 0;
}
int my_signal_cb(void* a, void* b, void* c, void* d)
{
@@ -740,26 +1037,22 @@ int my_signal_cb(void* a, void* b, void* c, void* d)
// hopefully, no callback have more than 4 arguments...
my_signal_t* sig = NULL;
int i = 0;
if(a)
if(((my_signal_t*)a)->sign == SIGN) {
sig = (my_signal_t*)a;
i = 1;
}
if(!sig && b)
if(((my_signal_t*)b)->sign == SIGN) {
sig = (my_signal_t*)b;
i = 2;
}
if(!sig && c)
if(((my_signal_t*)c)->sign == SIGN) {
sig = (my_signal_t*)c;
i = 3;
}
if(!sig && d)
if(((my_signal_t*)d)->sign == SIGN) {
sig = (my_signal_t*)d;
i = 4;
}
if(my_signal_is_valid(a)) {
sig = (my_signal_t*)a;
i = 1;
}
if(!sig && my_signal_is_valid(b)) {
sig = (my_signal_t*)b;
i = 2;
}
if(!sig && my_signal_is_valid(c)) {
sig = (my_signal_t*)c;
i = 3;
}
if(!sig && my_signal_is_valid(d)) {
sig = (my_signal_t*)d;
i = 4;
}
printf_log(LOG_DEBUG, "gtk Signal called, sig=%p, NArgs=%d\n", sig, i);
switch(i) {
case 1: return (int)RunFunction(my_context, sig->c_handler, 1, sig->data);
+17 -1
View File
@@ -7,6 +7,7 @@
#include "wine_tools.h"
#include "debug.h"
#include "box86context.h"
typedef struct wine_prereserve_s
{
@@ -86,4 +87,19 @@ void* get_wine_prereserve()
if(!wine_preloaded)
wine_prereserve(NULL);
return (void*)my_wine_reserve;
}
}
#ifdef DYNAREC
void dynarec_wine_prereserve()
{
#if 0
// disable for now, as it brack some installer
if(!wine_preloaded)
wine_prereserve(NULL);
// don't reserve the initial arbritrary block as "with linker", it's not true
for(int i=1; i<sizeof(my_wine_reserve)/sizeof(my_wine_reserve[0]); ++i)
if(my_wine_reserve[i].addr && my_wine_reserve[i].size)
addDBFromAddressRange(my_context, (uintptr_t)my_wine_reserve[i].addr, my_wine_reserve[i].size, 0); // prepare the prereserved area for exec, with linker
#endif
}
#endif
+189 -1
View File
@@ -5,14 +5,17 @@
#() vFu
#() vFf
#() vFd
#() vFl
#() vFL
#() vFp
#() vFS
#() vFG
#() cFv
#() cFi
#() cFu
#() cFf
#() cFp
#() cFG
#() wFp
#() iFE
#() iFv
@@ -27,13 +30,16 @@
#() iFL
#() iFp
#() iFS
#() iFG
#() IFv
#() IFi
#() IFf
#() IFd
#() IFp
#() IFG
#() CFC
#() CFp
#() CFG
#() WFi
#() WFp
#() uFE
@@ -43,24 +49,30 @@
#() uFU
#() uFd
#() uFp
#() uFG
#() UFv
#() UFp
#() UFV
#() UFG
#() fFi
#() fFf
#() fFp
#() fFG
#() dFv
#() dFi
#() dFu
#() dFd
#() dFp
#() dFG
#() lFv
#() lFi
#() lFl
#() lFp
#() lFG
#() LFv
#() LFu
#() LFp
#() LFG
#() pFE
#() pFv
#() pFw
@@ -75,6 +87,7 @@
#() pFL
#() pFp
#() pFV
#() pFG
#() vFEp
#() vFii
#() vFiI
@@ -95,7 +108,6 @@
#() vFfp
#() vFdd
#() vFLp
#() vFpc
#() vFpi
#() vFpI
#() vFpC
@@ -108,7 +120,21 @@
#() vFpL
#() vFpp
#() vFpS
#() vFpP
#() vFpG
#() vFSi
#() vFGc
#() vFGi
#() vFGI
#() vFGC
#() vFGu
#() vFGU
#() vFGf
#() vFGd
#() vFGl
#() vFGL
#() vFGp
#() vFGG
#() cFpp
#() iFEL
#() iFEp
@@ -137,7 +163,10 @@
#() iFpL
#() iFpp
#() iFpO
#() iFpP
#() iFpG
#() iFSi
#() iFGG
#() IFEp
#() IFII
#() IFpu
@@ -182,6 +211,7 @@
#() lFpi
#() lFpp
#() LFii
#() LFLi
#() LFLp
#() LFpL
#() LFpp
@@ -197,6 +227,7 @@
#() pFuC
#() pFuu
#() pFup
#() pFuV
#() pFUi
#() pFdd
#() pFlp
@@ -210,6 +241,7 @@
#() pFpL
#() pFpp
#() pFpV
#() pFpG
#() pFSi
#() vFEpi
#() vFEpu
@@ -252,10 +284,15 @@
#() vFpif
#() vFpid
#() vFpip
#() vFpiP
#() vFpui
#() vFpuI
#() vFpuu
#() vFpup
#() vFpUi
#() vFpUu
#() vFpUU
#() vFpUp
#() vFpff
#() vFpdd
#() vFpll
@@ -264,10 +301,14 @@
#() vFpLp
#() vFppi
#() vFppu
#() vFppU
#() vFppd
#() vFppL
#() vFppp
#() vFppV
#() vFppG
#() vFpPp
#() vFpPP
#() iFEiw
#() iFEip
#() iFEWW
@@ -315,7 +356,11 @@
#() iFpuL
#() iFpup
#() iFpu2
#() iFpuP
#() iFpUi
#() iFpUU
#() iFpUp
#() iFpUP
#() iFpfu
#() iFpff
#() iFpdd
@@ -334,6 +379,10 @@
#() iFppL
#() iFppp
#() iFppV
#() iFppG
#() iFpPp
#() iFpPP
#() iFpGG
#() iFSpi
#() iFSpu
#() IFiIi
@@ -358,6 +407,7 @@
#() uFpii
#() uFpiu
#() uFpip
#() uFpCi
#() uFpui
#() uFpuu
#() uFpup
@@ -375,6 +425,7 @@
#() fFppp
#() dFddd
#() dFddp
#() dFpdd
#() dFppi
#() dFppu
#() dFppp
@@ -384,10 +435,12 @@
#() lFpLp
#() lFppi
#() lFppL
#() LFiii
#() LFpii
#() LFpLi
#() LFpLp
#() LFppi
#() LFppp
#() pFEip
#() pFEup
#() pFEpi
@@ -424,6 +477,7 @@
#() pFpui
#() pFpuu
#() pFpup
#() pFpuG
#() pFpUp
#() pFpdu
#() pFplC
@@ -448,6 +502,7 @@
#() vFEpip
#() vFEpuu
#() vFEpup
#() vFEpUp
#() vFEppp
#() vFEppV
#() vFiiii
@@ -496,10 +551,12 @@
#() vFpiuu
#() vFpiuL
#() vFpiup
#() vFpiUu
#() vFpifi
#() vFpipi
#() vFpipu
#() vFpipp
#() vFpipG
#() vFpCiW
#() vFpuip
#() vFpuui
@@ -508,14 +565,23 @@
#() vFpuuV
#() vFpudd
#() vFpupp
#() vFpUui
#() vFpUuu
#() vFpUup
#() vFpUUi
#() vFpUUp
#() vFpUpp
#() vFpfff
#() vFpdii
#() vFpddd
#() vFpLLL
#() vFppii
#() vFppiu
#() vFppid
#() vFppil
#() vFppiL
#() vFppip
#() vFppiG
#() vFppui
#() vFppuu
#() vFppup
@@ -532,6 +598,8 @@
#() vFpppL
#() vFpppp
#() vFpppV
#() vFpppG
#() vFpPpp
#() vFSppi
#() cFpiii
#() iFEiip
@@ -542,6 +610,7 @@
#() iFEpip
#() iFEpuu
#() iFEpup
#() iFEpUp
#() iFEpLi
#() iFEppi
#() iFEppu
@@ -551,6 +620,7 @@
#() iFEpVV
#() iFEpOu
#() iFEpOV
#() iFEPpp
#() iFwwww
#() iFwppp
#() iFiiii
@@ -592,6 +662,8 @@
#() iFpipi
#() iFpipC
#() iFpipp
#() iFpipV
#() iFpIip
#() iFpCCC
#() iFpCpi
#() iFpWWu
@@ -602,11 +674,17 @@
#() iFpuui
#() iFpuuu
#() iFpuup
#() iFpuUp
#() iFpuLL
#() iFpuLp
#() iFpupi
#() iFpupu
#() iFpupp
#() iFpupV
#() iFpuPU
#() iFpUup
#() iFpUUU
#() iFpUpp
#() iFplii
#() iFplip
#() iFpLwp
@@ -620,6 +698,7 @@
#() iFppui
#() iFppuu
#() iFppup
#() iFppdp
#() iFppll
#() iFpplp
#() iFppLi
@@ -630,6 +709,8 @@
#() iFpppu
#() iFpppL
#() iFpppp
#() iFpPpp
#() iFpGGi
#() IFEpIi
#() IFpIip
#() IFppii
@@ -654,6 +735,7 @@
#() uFppiu
#() uFppip
#() uFppup
#() uFppLp
#() uFpppi
#() uFpppp
#() UFppii
@@ -694,6 +776,7 @@
#() pFiipi
#() pFipii
#() pFipip
#() pFippi
#() pFippu
#() pFuiii
#() pFffff
@@ -718,6 +801,7 @@
#() pFppip
#() pFppuu
#() pFppup
#() pFppLp
#() pFpppi
#() pFpppu
#() pFpppL
@@ -729,6 +813,7 @@
#() vFEpupp
#() vFEpLLp
#() vFEppip
#() vFEppup
#() vFEpppp
#() vFiiiii
#() vFiiiiu
@@ -792,7 +877,15 @@
#() vFpuipp
#() vFpuipV
#() vFpuuuu
#() vFpuuup
#() vFpuupp
#() vFpuddd
#() vFpupup
#() vFpUuiu
#() vFpUUuu
#() vFpUUup
#() vFpUUUu
#() vFpUUUp
#() vFpffff
#() vFpddii
#() vFpdddd
@@ -826,6 +919,7 @@
#() iFEpipi
#() iFEpipp
#() iFEpupV
#() iFEpUup
#() iFEpLpp
#() iFEpLpV
#() iFEppii
@@ -835,6 +929,7 @@
#() iFEpppp
#() iFEpppV
#() iFEppVV
#() iFEpPpp
#() iFiiipu
#() iFiiipp
#() iFiiupp
@@ -865,6 +960,7 @@
#() iFpipip
#() iFpippi
#() iFpippp
#() iFpipGp
#() iFpCCCC
#() iFpuiii
#() iFpuiup
@@ -874,6 +970,7 @@
#() iFpuuLL
#() iFpuupu
#() iFpuupp
#() iFpupiU
#() iFpupuu
#() iFpupup
#() iFpuppu
@@ -889,8 +986,10 @@
#() iFppupi
#() iFppupp
#() iFppllp
#() iFpplpp
#() iFppLwp
#() iFppLip
#() iFppLpi
#() iFppLpL
#() iFpppii
#() iFpppiu
@@ -902,8 +1001,10 @@
#() iFppppu
#() iFppppL
#() iFppppp
#() iFpppGp
#() IFppIII
#() uFEippp
#() uFEpipp
#() uFEppuu
#() uFEpppp
#() uFiuuuu
@@ -925,6 +1026,7 @@
#() LFEpppp
#() LFpuppi
#() LFpLppp
#() LFpppii
#() LFppppp
#() pFEpiii
#() pFEpipi
@@ -934,8 +1036,11 @@
#() pFEppii
#() pFEppip
#() pFEppCC
#() pFEppuW
#() pFEppuu
#() pFEppup
#() pFEpppi
#() pFEpppu
#() pFEpppp
#() pFiiiii
#() pFipipu
@@ -950,6 +1055,7 @@
#() pFpiipp
#() pFpiCCC
#() pFpiuuu
#() pFpippi
#() pFpippp
#() pFpuiii
#() pFpuuip
@@ -975,7 +1081,9 @@
#() vFEpiLpp
#() vFEpippp
#() vFEpuipp
#() vFEpupup
#() vFEpLLpp
#() vFEppupp
#() vFEppppp
#() vFiiiiii
#() vFiiiuil
@@ -1026,9 +1134,16 @@
#() vFpipiiu
#() vFpipipV
#() vFpipppi
#() vFpipppp
#() vFpuiiiu
#() vFpuiipp
#() vFpuuuiu
#() vFpuuppp
#() vFpudddd
#() vFpUiuup
#() vFpUiUup
#() vFpUipup
#() vFpUUiup
#() vFpdddii
#() vFpddddd
#() vFppiiii
@@ -1038,11 +1153,15 @@
#() vFppiipp
#() vFppilpp
#() vFppippi
#() vFppippp
#() vFppuuuu
#() vFppupii
#() vFppuppp
#() vFppdidd
#() vFpplppi
#() vFpplppp
#() vFppLppi
#() vFppLppp
#() vFpppiii
#() vFpppiip
#() vFpppiff
@@ -1053,6 +1172,7 @@
#() vFpppppu
#() vFpppppL
#() vFpppppp
#() cFppLppi
#() iFEiippi
#() iFEiippp
#() iFEipuup
@@ -1066,6 +1186,7 @@
#() iFEpuuip
#() iFEpuppp
#() iFEpupVV
#() iFEpUPpp
#() iFEpLppp
#() iFEppppp
#() iFiiiiii
@@ -1098,6 +1219,8 @@
#() iFpuiiii
#() iFpupipi
#() iFpupuui
#() iFpUUUip
#() iFpUUUUp
#() iFppiiip
#() iFppiiuu
#() iFppiipi
@@ -1105,18 +1228,22 @@
#() iFppipii
#() iFppipiL
#() iFppipip
#() iFppIipp
#() iFppIppp
#() iFppuiii
#() iFppuiiu
#() iFppuipp
#() iFppuIII
#() iFppuupp
#() iFppupip
#() iFppuppp
#() iFppUipp
#() iFppUupp
#() iFppdidd
#() iFpplppi
#() iFppLupp
#() iFppLpLp
#() iFppLppp
#() iFpppiuu
#() iFpppipp
#() iFpppuii
@@ -1129,6 +1256,7 @@
#() iFpppppu
#() iFpppppp
#() uFEiippp
#() uFEiuppp
#() uFpippup
#() uFppippp
#() uFpppppp
@@ -1144,19 +1272,25 @@
#() pFEppCuW
#() pFEppCuu
#() pFEppuWp
#() pFEppuuC
#() pFEppuuu
#() pFEppuup
#() pFEpppup
#() pFEppppi
#() pFEppppp
#() pFiiiiii
#() pFiCiiCi
#() pFdddddd
#() pFpiiiiu
#() pFpiiCCC
#() pFpiiuuu
#() pFpippip
#() pFpuuuuu
#() pFplpppp
#() pFppiiii
#() pFppiipp
#() pFppiCCC
#() pFppippi
#() pFppippp
#() pFpppiii
#() pFpppiui
@@ -1166,6 +1300,8 @@
#() pFpppppp
#() pFSpiiii
#() vFEpipppp
#() vFEpuipuV
#() vFEpppppp
#() vFiiiiiip
#() vFiiiiuup
#() vFiiupuip
@@ -1205,6 +1341,10 @@
#() vFpiiliip
#() vFpiipCpp
#() vFpipipii
#() vFpipppii
#() vFpuuuuuu
#() vFpuuUUuu
#() vFpUiUiup
#() vFpddiidd
#() vFpdddddd
#() vFppiiiii
@@ -1217,15 +1357,22 @@
#() vFppipiip
#() vFppipipp
#() vFppipppp
#() vFppLpppi
#() vFppLpppp
#() vFpppiiii
#() vFpppiipi
#() vFpppiipp
#() vFpppippi
#() vFpppuuuu
#() vFppppiii
#() vFppppiip
#() vFppppipi
#() vFpppppip
#() vFppppppi
#() vFppppppp
#() iFEpuiupV
#() iFEpupppp
#() iFEpUuppp
#() iFEppiuui
#() iFEppupIi
#() iFEppuppp
@@ -1234,6 +1381,7 @@
#() iFiiiiiip
#() iFiuppppp
#() iFpiiiiii
#() iFpiiiiip
#() iFpiiiLwp
#() iFpiiuuiu
#() iFpiiuuuu
@@ -1259,23 +1407,29 @@
#() iFppiipiL
#() iFppipiip
#() iFppipipi
#() iFppipipp
#() iFppippip
#() iFppipppi
#() iFppipppp
#() iFppuipiL
#() iFppLiipp
#() iFpppiiii
#() iFpppiiuu
#() iFpppiiup
#() iFpppiipi
#() iFpppiuwu
#() iFpppippi
#() iFpppippp
#() iFpppuiii
#() iFpppuppp
#() iFppppiii
#() iFppppipp
#() iFppppdpi
#() iFpppppip
#() iFpppppup
#() iFppppppi
#() iFppppppp
#() uFEpiippp
#() uFuippppp
#() LFEpppppu
#() pFEpLiiii
@@ -1292,9 +1446,13 @@
#() pFuupupup
#() pFplppppp
#() pFppiiipp
#() pFppiiCCC
#() pFppiippp
#() pFppipipp
#() pFppuuuuu
#() pFppuuppp
#() pFppLiiip
#() pFppLipip
#() pFpppccci
#() pFpppiiii
#() pFpppiipp
@@ -1309,6 +1467,7 @@
#() pFpppLLLi
#() pFppppuuu
#() pFpppppuu
#() pFppppppi
#() pFppppppp
#() vFEiippppV
#() vFEiupippp
@@ -1339,10 +1498,15 @@
#() vFffffffff
#() vFpiiiiiii
#() vFpiiiipii
#() vFpiiULipp
#() vFpiUuupup
#() vFpippiiuu
#() vFpippiipi
#() vFpUiUiupi
#() vFpUuuUUUi
#() vFppiiiiii
#() vFppiiipii
#() vFppipipii
#() vFppipppui
#() vFppippppi
#() vFppippppp
@@ -1368,12 +1532,16 @@
#() iFpuippupp
#() iFpuuiiiii
#() iFpupppppp
#() iFpUuuLpUi
#() iFppiiiiiu
#() iFppIIIppp
#() iFpppiippp
#() iFpppipipi
#() iFpppipppp
#() iFppppiipi
#() iFppppippp
#() iFppppppii
#() iFpppppppi
#() iFpppppppp
#() uFEipipppp
#() uFEpiupppp
@@ -1384,6 +1552,7 @@
#() pFEppCuuCC
#() pFEppCuuWW
#() pFEppCuuup
#() pFEppuuwwu
#() pFEppuuuuu
#() pFEppuuUUU
#() pFEppLiiip
@@ -1398,11 +1567,13 @@
#() pFpipppppp
#() pFpWWiCpup
#() pFpuuuupup
#() pFpupupuuu
#() pFpdwwWWui
#() pFplpppppp
#() pFppiiiiii
#() pFpppuuuuu
#() pFpppppupp
#() vFEpiiiiipp
#() vFEppiipppp
#() vFEpppiippp
#() vFuiiiiiiii
@@ -1431,6 +1602,7 @@
#() vFppuuiiiii
#() vFpplpppppi
#() vFpppiiiiii
#() vFppppipiip
#() vFpppppippp
#() vFppppppppp
#() iFEiiuuuuuu
@@ -1438,6 +1610,7 @@
#() iFEpuuiippu
#() iFEpuuuiipp
#() iFEpppipppp
#() iFEpppppupp
#() iFiiiiiiiip
#() iFiiiipiiip
#() iFipiipippi
@@ -1450,6 +1623,7 @@
#() iFppiiiiiii
#() iFppiuiippu
#() iFppipiiipi
#() iFppLpiippp
#() iFpppiiuuii
#() iFpppiipiiu
#() iFppppupiii
@@ -1460,9 +1634,11 @@
#() LFEppppppii
#() pFEppiiuuui
#() pFEppCuwwWW
#() pFEppCuWCCC
#() pFEppCuuwwp
#() pFEppCuuuuu
#() pFEppuippuu
#() pFEppuuuwwu
#() pFEppuupwwC
#() pFEpppppiiV
#() pFEpppppppi
@@ -1474,6 +1650,7 @@
#() pFppipppppp
#() pFpppiiiiii
#() pFpppiipppp
#() pFpppppiipp
#() vFEiippppppp
#() vFEpippppppp
#() vFEpppiipppp
@@ -1509,6 +1686,7 @@
#() iFiiiiiiiiip
#() iFpuipuppppp
#() iFpuupiuiipp
#() iFppipiippii
#() iFppuuiiiiii
#() iFppuuiiuupi
#() iFpppLLipppp
@@ -1517,10 +1695,13 @@
#() pFEiippppppp
#() pFEpiiiiiipp
#() pFEpippppppp
#() pFEppCCuuwwC
#() pFEppCuwwWWu
#() pFEppCuuuCup
#() pFEppuuWWCuu
#() pFplllllllll
#() pFppuiipuuii
#() vFEpiiiupupup
#() vFiippppppppp
#() vFuiiiiiiiiip
#() vFuiiiiiiiuip
@@ -1534,6 +1715,7 @@
#() vFuffffffffff
#() vFpipipiipiii
#() vFpipppiiiipi
#() vFpupiiuPuPuP
#() vFppiiiiiiiii
#() vFppiiiiipiii
#() vFppiiiiddddi
@@ -1548,6 +1730,7 @@
#() iFEppppiiiiuu
#() iFiiiiiiiiiip
#() iFpipllippppp
#() iFppippipppip
#() iFppppiiuuiiu
#() uFEpiiupppiuV
#() uFEpiippppiup
@@ -1578,6 +1761,8 @@
#() iFpppppppppppp
#() lFpLpppppppppp
#() pFEppiiuuuipii
#() pFEppCuWCCuuCW
#() pFEppuwwWWuCuu
#() pFEppuuuwwwwWW
#() pFEppuuuWWWCCi
#() pFWWiCCCCiipup
@@ -1630,12 +1815,15 @@
#() pFppippipipipipipip
#() vFppuiiiiipuiiiiiiii
#() vFpppipppppppppppppp
#() LFpppppppppppppppppp
#() pFEppuuWWWWWWwwCCCuu
#() pFippppppppppppppppp
#() vFpiiiiiiiiiiiiiiiiii
#() iFpppippppppppppppppp
#() pFEppuuuuuwwuuuuUUUup
#() pFiiiippppppppppppppp
#() pFipppppppppppppppppppppp
#() iFpppppppppppppppppppppppppppppppppp
#defined(NOALIGN) IFpi
#defined(NOALIGN) dFpi
#defined(NOALIGN) iFppiiiip
File diff suppressed because it is too large. Load diff
+192 -1
View File
@@ -4,6 +4,7 @@
#ifndef __WRAPPER_H_
#define __WRAPPER_H_
#include <stdint.h>
#include <string.h>
typedef struct x86emu_s x86emu_t;
@@ -24,6 +25,8 @@ typedef void (*wrapper_t)(x86emu_t* emu, uintptr_t fnc);
// S = _IO_2_1_stdXXX_ pointer (or FILE*)
// Q = ...
// 2 = struct of 2 uint
// P = Vulkan struture pointer
// G = a single GValue pointer
void iF(x86emu_t *emu, uintptr_t fnc);
void vFE(x86emu_t *emu, uintptr_t fnc);
@@ -32,14 +35,17 @@ void vFi(x86emu_t *emu, uintptr_t fnc);
void vFu(x86emu_t *emu, uintptr_t fnc);
void vFf(x86emu_t *emu, uintptr_t fnc);
void vFd(x86emu_t *emu, uintptr_t fnc);
void vFl(x86emu_t *emu, uintptr_t fnc);
void vFL(x86emu_t *emu, uintptr_t fnc);
void vFp(x86emu_t *emu, uintptr_t fnc);
void vFS(x86emu_t *emu, uintptr_t fnc);
void vFG(x86emu_t *emu, uintptr_t fnc);
void cFv(x86emu_t *emu, uintptr_t fnc);
void cFi(x86emu_t *emu, uintptr_t fnc);
void cFu(x86emu_t *emu, uintptr_t fnc);
void cFf(x86emu_t *emu, uintptr_t fnc);
void cFp(x86emu_t *emu, uintptr_t fnc);
void cFG(x86emu_t *emu, uintptr_t fnc);
void wFp(x86emu_t *emu, uintptr_t fnc);
void iFE(x86emu_t *emu, uintptr_t fnc);
void iFv(x86emu_t *emu, uintptr_t fnc);
@@ -54,13 +60,16 @@ void iFd(x86emu_t *emu, uintptr_t fnc);
void iFL(x86emu_t *emu, uintptr_t fnc);
void iFp(x86emu_t *emu, uintptr_t fnc);
void iFS(x86emu_t *emu, uintptr_t fnc);
void iFG(x86emu_t *emu, uintptr_t fnc);
void IFv(x86emu_t *emu, uintptr_t fnc);
void IFi(x86emu_t *emu, uintptr_t fnc);
void IFf(x86emu_t *emu, uintptr_t fnc);
void IFd(x86emu_t *emu, uintptr_t fnc);
void IFp(x86emu_t *emu, uintptr_t fnc);
void IFG(x86emu_t *emu, uintptr_t fnc);
void CFC(x86emu_t *emu, uintptr_t fnc);
void CFp(x86emu_t *emu, uintptr_t fnc);
void CFG(x86emu_t *emu, uintptr_t fnc);
void WFi(x86emu_t *emu, uintptr_t fnc);
void WFp(x86emu_t *emu, uintptr_t fnc);
void uFE(x86emu_t *emu, uintptr_t fnc);
@@ -70,24 +79,30 @@ void uFu(x86emu_t *emu, uintptr_t fnc);
void uFU(x86emu_t *emu, uintptr_t fnc);
void uFd(x86emu_t *emu, uintptr_t fnc);
void uFp(x86emu_t *emu, uintptr_t fnc);
void uFG(x86emu_t *emu, uintptr_t fnc);
void UFv(x86emu_t *emu, uintptr_t fnc);
void UFp(x86emu_t *emu, uintptr_t fnc);
void UFV(x86emu_t *emu, uintptr_t fnc);
void UFG(x86emu_t *emu, uintptr_t fnc);
void fFi(x86emu_t *emu, uintptr_t fnc);
void fFf(x86emu_t *emu, uintptr_t fnc);
void fFp(x86emu_t *emu, uintptr_t fnc);
void fFG(x86emu_t *emu, uintptr_t fnc);
void dFv(x86emu_t *emu, uintptr_t fnc);
void dFi(x86emu_t *emu, uintptr_t fnc);
void dFu(x86emu_t *emu, uintptr_t fnc);
void dFd(x86emu_t *emu, uintptr_t fnc);
void dFp(x86emu_t *emu, uintptr_t fnc);
void dFG(x86emu_t *emu, uintptr_t fnc);
void lFv(x86emu_t *emu, uintptr_t fnc);
void lFi(x86emu_t *emu, uintptr_t fnc);
void lFl(x86emu_t *emu, uintptr_t fnc);
void lFp(x86emu_t *emu, uintptr_t fnc);
void lFG(x86emu_t *emu, uintptr_t fnc);
void LFv(x86emu_t *emu, uintptr_t fnc);
void LFu(x86emu_t *emu, uintptr_t fnc);
void LFp(x86emu_t *emu, uintptr_t fnc);
void LFG(x86emu_t *emu, uintptr_t fnc);
void pFE(x86emu_t *emu, uintptr_t fnc);
void pFv(x86emu_t *emu, uintptr_t fnc);
void pFw(x86emu_t *emu, uintptr_t fnc);
@@ -102,6 +117,7 @@ void pFl(x86emu_t *emu, uintptr_t fnc);
void pFL(x86emu_t *emu, uintptr_t fnc);
void pFp(x86emu_t *emu, uintptr_t fnc);
void pFV(x86emu_t *emu, uintptr_t fnc);
void pFG(x86emu_t *emu, uintptr_t fnc);
void vFEp(x86emu_t *emu, uintptr_t fnc);
void vFii(x86emu_t *emu, uintptr_t fnc);
void vFiI(x86emu_t *emu, uintptr_t fnc);
@@ -122,7 +138,6 @@ void vFff(x86emu_t *emu, uintptr_t fnc);
void vFfp(x86emu_t *emu, uintptr_t fnc);
void vFdd(x86emu_t *emu, uintptr_t fnc);
void vFLp(x86emu_t *emu, uintptr_t fnc);
void vFpc(x86emu_t *emu, uintptr_t fnc);
void vFpi(x86emu_t *emu, uintptr_t fnc);
void vFpI(x86emu_t *emu, uintptr_t fnc);
void vFpC(x86emu_t *emu, uintptr_t fnc);
@@ -135,7 +150,21 @@ void vFpl(x86emu_t *emu, uintptr_t fnc);
void vFpL(x86emu_t *emu, uintptr_t fnc);
void vFpp(x86emu_t *emu, uintptr_t fnc);
void vFpS(x86emu_t *emu, uintptr_t fnc);
void vFpP(x86emu_t *emu, uintptr_t fnc);
void vFpG(x86emu_t *emu, uintptr_t fnc);
void vFSi(x86emu_t *emu, uintptr_t fnc);
void vFGc(x86emu_t *emu, uintptr_t fnc);
void vFGi(x86emu_t *emu, uintptr_t fnc);
void vFGI(x86emu_t *emu, uintptr_t fnc);
void vFGC(x86emu_t *emu, uintptr_t fnc);
void vFGu(x86emu_t *emu, uintptr_t fnc);
void vFGU(x86emu_t *emu, uintptr_t fnc);
void vFGf(x86emu_t *emu, uintptr_t fnc);
void vFGd(x86emu_t *emu, uintptr_t fnc);
void vFGl(x86emu_t *emu, uintptr_t fnc);
void vFGL(x86emu_t *emu, uintptr_t fnc);
void vFGp(x86emu_t *emu, uintptr_t fnc);
void vFGG(x86emu_t *emu, uintptr_t fnc);
void cFpp(x86emu_t *emu, uintptr_t fnc);
void iFEL(x86emu_t *emu, uintptr_t fnc);
void iFEp(x86emu_t *emu, uintptr_t fnc);
@@ -164,7 +193,10 @@ void iFpl(x86emu_t *emu, uintptr_t fnc);
void iFpL(x86emu_t *emu, uintptr_t fnc);
void iFpp(x86emu_t *emu, uintptr_t fnc);
void iFpO(x86emu_t *emu, uintptr_t fnc);
void iFpP(x86emu_t *emu, uintptr_t fnc);
void iFpG(x86emu_t *emu, uintptr_t fnc);
void iFSi(x86emu_t *emu, uintptr_t fnc);
void iFGG(x86emu_t *emu, uintptr_t fnc);
void IFEp(x86emu_t *emu, uintptr_t fnc);
void IFII(x86emu_t *emu, uintptr_t fnc);
void IFpu(x86emu_t *emu, uintptr_t fnc);
@@ -209,6 +241,7 @@ void lFll(x86emu_t *emu, uintptr_t fnc);
void lFpi(x86emu_t *emu, uintptr_t fnc);
void lFpp(x86emu_t *emu, uintptr_t fnc);
void LFii(x86emu_t *emu, uintptr_t fnc);
void LFLi(x86emu_t *emu, uintptr_t fnc);
void LFLp(x86emu_t *emu, uintptr_t fnc);
void LFpL(x86emu_t *emu, uintptr_t fnc);
void LFpp(x86emu_t *emu, uintptr_t fnc);
@@ -224,6 +257,7 @@ void pFui(x86emu_t *emu, uintptr_t fnc);
void pFuC(x86emu_t *emu, uintptr_t fnc);
void pFuu(x86emu_t *emu, uintptr_t fnc);
void pFup(x86emu_t *emu, uintptr_t fnc);
void pFuV(x86emu_t *emu, uintptr_t fnc);
void pFUi(x86emu_t *emu, uintptr_t fnc);
void pFdd(x86emu_t *emu, uintptr_t fnc);
void pFlp(x86emu_t *emu, uintptr_t fnc);
@@ -237,6 +271,7 @@ void pFpl(x86emu_t *emu, uintptr_t fnc);
void pFpL(x86emu_t *emu, uintptr_t fnc);
void pFpp(x86emu_t *emu, uintptr_t fnc);
void pFpV(x86emu_t *emu, uintptr_t fnc);
void pFpG(x86emu_t *emu, uintptr_t fnc);
void pFSi(x86emu_t *emu, uintptr_t fnc);
void vFEpi(x86emu_t *emu, uintptr_t fnc);
void vFEpu(x86emu_t *emu, uintptr_t fnc);
@@ -279,10 +314,15 @@ void vFpiu(x86emu_t *emu, uintptr_t fnc);
void vFpif(x86emu_t *emu, uintptr_t fnc);
void vFpid(x86emu_t *emu, uintptr_t fnc);
void vFpip(x86emu_t *emu, uintptr_t fnc);
void vFpiP(x86emu_t *emu, uintptr_t fnc);
void vFpui(x86emu_t *emu, uintptr_t fnc);
void vFpuI(x86emu_t *emu, uintptr_t fnc);
void vFpuu(x86emu_t *emu, uintptr_t fnc);
void vFpup(x86emu_t *emu, uintptr_t fnc);
void vFpUi(x86emu_t *emu, uintptr_t fnc);
void vFpUu(x86emu_t *emu, uintptr_t fnc);
void vFpUU(x86emu_t *emu, uintptr_t fnc);
void vFpUp(x86emu_t *emu, uintptr_t fnc);
void vFpff(x86emu_t *emu, uintptr_t fnc);
void vFpdd(x86emu_t *emu, uintptr_t fnc);
void vFpll(x86emu_t *emu, uintptr_t fnc);
@@ -291,10 +331,14 @@ void vFpLL(x86emu_t *emu, uintptr_t fnc);
void vFpLp(x86emu_t *emu, uintptr_t fnc);
void vFppi(x86emu_t *emu, uintptr_t fnc);
void vFppu(x86emu_t *emu, uintptr_t fnc);
void vFppU(x86emu_t *emu, uintptr_t fnc);
void vFppd(x86emu_t *emu, uintptr_t fnc);
void vFppL(x86emu_t *emu, uintptr_t fnc);
void vFppp(x86emu_t *emu, uintptr_t fnc);
void vFppV(x86emu_t *emu, uintptr_t fnc);
void vFppG(x86emu_t *emu, uintptr_t fnc);
void vFpPp(x86emu_t *emu, uintptr_t fnc);
void vFpPP(x86emu_t *emu, uintptr_t fnc);
void iFEiw(x86emu_t *emu, uintptr_t fnc);
void iFEip(x86emu_t *emu, uintptr_t fnc);
void iFEWW(x86emu_t *emu, uintptr_t fnc);
@@ -342,7 +386,11 @@ void iFpuu(x86emu_t *emu, uintptr_t fnc);
void iFpuL(x86emu_t *emu, uintptr_t fnc);
void iFpup(x86emu_t *emu, uintptr_t fnc);
void iFpu2(x86emu_t *emu, uintptr_t fnc);
void iFpuP(x86emu_t *emu, uintptr_t fnc);
void iFpUi(x86emu_t *emu, uintptr_t fnc);
void iFpUU(x86emu_t *emu, uintptr_t fnc);
void iFpUp(x86emu_t *emu, uintptr_t fnc);
void iFpUP(x86emu_t *emu, uintptr_t fnc);
void iFpfu(x86emu_t *emu, uintptr_t fnc);
void iFpff(x86emu_t *emu, uintptr_t fnc);
void iFpdd(x86emu_t *emu, uintptr_t fnc);
@@ -361,6 +409,10 @@ void iFppl(x86emu_t *emu, uintptr_t fnc);
void iFppL(x86emu_t *emu, uintptr_t fnc);
void iFppp(x86emu_t *emu, uintptr_t fnc);
void iFppV(x86emu_t *emu, uintptr_t fnc);
void iFppG(x86emu_t *emu, uintptr_t fnc);
void iFpPp(x86emu_t *emu, uintptr_t fnc);
void iFpPP(x86emu_t *emu, uintptr_t fnc);
void iFpGG(x86emu_t *emu, uintptr_t fnc);
void iFSpi(x86emu_t *emu, uintptr_t fnc);
void iFSpu(x86emu_t *emu, uintptr_t fnc);
void IFiIi(x86emu_t *emu, uintptr_t fnc);
@@ -385,6 +437,7 @@ void uFupp(x86emu_t *emu, uintptr_t fnc);
void uFpii(x86emu_t *emu, uintptr_t fnc);
void uFpiu(x86emu_t *emu, uintptr_t fnc);
void uFpip(x86emu_t *emu, uintptr_t fnc);
void uFpCi(x86emu_t *emu, uintptr_t fnc);
void uFpui(x86emu_t *emu, uintptr_t fnc);
void uFpuu(x86emu_t *emu, uintptr_t fnc);
void uFpup(x86emu_t *emu, uintptr_t fnc);
@@ -402,6 +455,7 @@ void fFppu(x86emu_t *emu, uintptr_t fnc);
void fFppp(x86emu_t *emu, uintptr_t fnc);
void dFddd(x86emu_t *emu, uintptr_t fnc);
void dFddp(x86emu_t *emu, uintptr_t fnc);
void dFpdd(x86emu_t *emu, uintptr_t fnc);
void dFppi(x86emu_t *emu, uintptr_t fnc);
void dFppu(x86emu_t *emu, uintptr_t fnc);
void dFppp(x86emu_t *emu, uintptr_t fnc);
@@ -411,10 +465,12 @@ void lFlll(x86emu_t *emu, uintptr_t fnc);
void lFpLp(x86emu_t *emu, uintptr_t fnc);
void lFppi(x86emu_t *emu, uintptr_t fnc);
void lFppL(x86emu_t *emu, uintptr_t fnc);
void LFiii(x86emu_t *emu, uintptr_t fnc);
void LFpii(x86emu_t *emu, uintptr_t fnc);
void LFpLi(x86emu_t *emu, uintptr_t fnc);
void LFpLp(x86emu_t *emu, uintptr_t fnc);
void LFppi(x86emu_t *emu, uintptr_t fnc);
void LFppp(x86emu_t *emu, uintptr_t fnc);
void pFEip(x86emu_t *emu, uintptr_t fnc);
void pFEup(x86emu_t *emu, uintptr_t fnc);
void pFEpi(x86emu_t *emu, uintptr_t fnc);
@@ -451,6 +507,7 @@ void pFpWW(x86emu_t *emu, uintptr_t fnc);
void pFpui(x86emu_t *emu, uintptr_t fnc);
void pFpuu(x86emu_t *emu, uintptr_t fnc);
void pFpup(x86emu_t *emu, uintptr_t fnc);
void pFpuG(x86emu_t *emu, uintptr_t fnc);
void pFpUp(x86emu_t *emu, uintptr_t fnc);
void pFpdu(x86emu_t *emu, uintptr_t fnc);
void pFplC(x86emu_t *emu, uintptr_t fnc);
@@ -475,6 +532,7 @@ void vFEpiL(x86emu_t *emu, uintptr_t fnc);
void vFEpip(x86emu_t *emu, uintptr_t fnc);
void vFEpuu(x86emu_t *emu, uintptr_t fnc);
void vFEpup(x86emu_t *emu, uintptr_t fnc);
void vFEpUp(x86emu_t *emu, uintptr_t fnc);
void vFEppp(x86emu_t *emu, uintptr_t fnc);
void vFEppV(x86emu_t *emu, uintptr_t fnc);
void vFiiii(x86emu_t *emu, uintptr_t fnc);
@@ -523,10 +581,12 @@ void vFpiip(x86emu_t *emu, uintptr_t fnc);
void vFpiuu(x86emu_t *emu, uintptr_t fnc);
void vFpiuL(x86emu_t *emu, uintptr_t fnc);
void vFpiup(x86emu_t *emu, uintptr_t fnc);
void vFpiUu(x86emu_t *emu, uintptr_t fnc);
void vFpifi(x86emu_t *emu, uintptr_t fnc);
void vFpipi(x86emu_t *emu, uintptr_t fnc);
void vFpipu(x86emu_t *emu, uintptr_t fnc);
void vFpipp(x86emu_t *emu, uintptr_t fnc);
void vFpipG(x86emu_t *emu, uintptr_t fnc);
void vFpCiW(x86emu_t *emu, uintptr_t fnc);
void vFpuip(x86emu_t *emu, uintptr_t fnc);
void vFpuui(x86emu_t *emu, uintptr_t fnc);
@@ -535,14 +595,23 @@ void vFpuup(x86emu_t *emu, uintptr_t fnc);
void vFpuuV(x86emu_t *emu, uintptr_t fnc);
void vFpudd(x86emu_t *emu, uintptr_t fnc);
void vFpupp(x86emu_t *emu, uintptr_t fnc);
void vFpUui(x86emu_t *emu, uintptr_t fnc);
void vFpUuu(x86emu_t *emu, uintptr_t fnc);
void vFpUup(x86emu_t *emu, uintptr_t fnc);
void vFpUUi(x86emu_t *emu, uintptr_t fnc);
void vFpUUp(x86emu_t *emu, uintptr_t fnc);
void vFpUpp(x86emu_t *emu, uintptr_t fnc);
void vFpfff(x86emu_t *emu, uintptr_t fnc);
void vFpdii(x86emu_t *emu, uintptr_t fnc);
void vFpddd(x86emu_t *emu, uintptr_t fnc);
void vFpLLL(x86emu_t *emu, uintptr_t fnc);
void vFppii(x86emu_t *emu, uintptr_t fnc);
void vFppiu(x86emu_t *emu, uintptr_t fnc);
void vFppid(x86emu_t *emu, uintptr_t fnc);
void vFppil(x86emu_t *emu, uintptr_t fnc);
void vFppiL(x86emu_t *emu, uintptr_t fnc);
void vFppip(x86emu_t *emu, uintptr_t fnc);
void vFppiG(x86emu_t *emu, uintptr_t fnc);
void vFppui(x86emu_t *emu, uintptr_t fnc);
void vFppuu(x86emu_t *emu, uintptr_t fnc);
void vFppup(x86emu_t *emu, uintptr_t fnc);
@@ -559,6 +628,8 @@ void vFpppd(x86emu_t *emu, uintptr_t fnc);
void vFpppL(x86emu_t *emu, uintptr_t fnc);
void vFpppp(x86emu_t *emu, uintptr_t fnc);
void vFpppV(x86emu_t *emu, uintptr_t fnc);
void vFpppG(x86emu_t *emu, uintptr_t fnc);
void vFpPpp(x86emu_t *emu, uintptr_t fnc);
void vFSppi(x86emu_t *emu, uintptr_t fnc);
void cFpiii(x86emu_t *emu, uintptr_t fnc);
void iFEiip(x86emu_t *emu, uintptr_t fnc);
@@ -569,6 +640,7 @@ void iFEpii(x86emu_t *emu, uintptr_t fnc);
void iFEpip(x86emu_t *emu, uintptr_t fnc);
void iFEpuu(x86emu_t *emu, uintptr_t fnc);
void iFEpup(x86emu_t *emu, uintptr_t fnc);
void iFEpUp(x86emu_t *emu, uintptr_t fnc);
void iFEpLi(x86emu_t *emu, uintptr_t fnc);
void iFEppi(x86emu_t *emu, uintptr_t fnc);
void iFEppu(x86emu_t *emu, uintptr_t fnc);
@@ -578,6 +650,7 @@ void iFEppV(x86emu_t *emu, uintptr_t fnc);
void iFEpVV(x86emu_t *emu, uintptr_t fnc);
void iFEpOu(x86emu_t *emu, uintptr_t fnc);
void iFEpOV(x86emu_t *emu, uintptr_t fnc);
void iFEPpp(x86emu_t *emu, uintptr_t fnc);
void iFwwww(x86emu_t *emu, uintptr_t fnc);
void iFwppp(x86emu_t *emu, uintptr_t fnc);
void iFiiii(x86emu_t *emu, uintptr_t fnc);
@@ -619,6 +692,8 @@ void iFpild(x86emu_t *emu, uintptr_t fnc);
void iFpipi(x86emu_t *emu, uintptr_t fnc);
void iFpipC(x86emu_t *emu, uintptr_t fnc);
void iFpipp(x86emu_t *emu, uintptr_t fnc);
void iFpipV(x86emu_t *emu, uintptr_t fnc);
void iFpIip(x86emu_t *emu, uintptr_t fnc);
void iFpCCC(x86emu_t *emu, uintptr_t fnc);
void iFpCpi(x86emu_t *emu, uintptr_t fnc);
void iFpWWu(x86emu_t *emu, uintptr_t fnc);
@@ -629,11 +704,17 @@ void iFpuip(x86emu_t *emu, uintptr_t fnc);
void iFpuui(x86emu_t *emu, uintptr_t fnc);
void iFpuuu(x86emu_t *emu, uintptr_t fnc);
void iFpuup(x86emu_t *emu, uintptr_t fnc);
void iFpuUp(x86emu_t *emu, uintptr_t fnc);
void iFpuLL(x86emu_t *emu, uintptr_t fnc);
void iFpuLp(x86emu_t *emu, uintptr_t fnc);
void iFpupi(x86emu_t *emu, uintptr_t fnc);
void iFpupu(x86emu_t *emu, uintptr_t fnc);
void iFpupp(x86emu_t *emu, uintptr_t fnc);
void iFpupV(x86emu_t *emu, uintptr_t fnc);
void iFpuPU(x86emu_t *emu, uintptr_t fnc);
void iFpUup(x86emu_t *emu, uintptr_t fnc);
void iFpUUU(x86emu_t *emu, uintptr_t fnc);
void iFpUpp(x86emu_t *emu, uintptr_t fnc);
void iFplii(x86emu_t *emu, uintptr_t fnc);
void iFplip(x86emu_t *emu, uintptr_t fnc);
void iFpLwp(x86emu_t *emu, uintptr_t fnc);
@@ -647,6 +728,7 @@ void iFppuw(x86emu_t *emu, uintptr_t fnc);
void iFppui(x86emu_t *emu, uintptr_t fnc);
void iFppuu(x86emu_t *emu, uintptr_t fnc);
void iFppup(x86emu_t *emu, uintptr_t fnc);
void iFppdp(x86emu_t *emu, uintptr_t fnc);
void iFppll(x86emu_t *emu, uintptr_t fnc);
void iFpplp(x86emu_t *emu, uintptr_t fnc);
void iFppLi(x86emu_t *emu, uintptr_t fnc);
@@ -657,6 +739,8 @@ void iFpppC(x86emu_t *emu, uintptr_t fnc);
void iFpppu(x86emu_t *emu, uintptr_t fnc);
void iFpppL(x86emu_t *emu, uintptr_t fnc);
void iFpppp(x86emu_t *emu, uintptr_t fnc);
void iFpPpp(x86emu_t *emu, uintptr_t fnc);
void iFpGGi(x86emu_t *emu, uintptr_t fnc);
void IFEpIi(x86emu_t *emu, uintptr_t fnc);
void IFpIip(x86emu_t *emu, uintptr_t fnc);
void IFppii(x86emu_t *emu, uintptr_t fnc);
@@ -681,6 +765,7 @@ void uFpupp(x86emu_t *emu, uintptr_t fnc);
void uFppiu(x86emu_t *emu, uintptr_t fnc);
void uFppip(x86emu_t *emu, uintptr_t fnc);
void uFppup(x86emu_t *emu, uintptr_t fnc);
void uFppLp(x86emu_t *emu, uintptr_t fnc);
void uFpppi(x86emu_t *emu, uintptr_t fnc);
void uFpppp(x86emu_t *emu, uintptr_t fnc);
void UFppii(x86emu_t *emu, uintptr_t fnc);
@@ -721,6 +806,7 @@ void pFiiup(x86emu_t *emu, uintptr_t fnc);
void pFiipi(x86emu_t *emu, uintptr_t fnc);
void pFipii(x86emu_t *emu, uintptr_t fnc);
void pFipip(x86emu_t *emu, uintptr_t fnc);
void pFippi(x86emu_t *emu, uintptr_t fnc);
void pFippu(x86emu_t *emu, uintptr_t fnc);
void pFuiii(x86emu_t *emu, uintptr_t fnc);
void pFffff(x86emu_t *emu, uintptr_t fnc);
@@ -745,6 +831,7 @@ void pFppiL(x86emu_t *emu, uintptr_t fnc);
void pFppip(x86emu_t *emu, uintptr_t fnc);
void pFppuu(x86emu_t *emu, uintptr_t fnc);
void pFppup(x86emu_t *emu, uintptr_t fnc);
void pFppLp(x86emu_t *emu, uintptr_t fnc);
void pFpppi(x86emu_t *emu, uintptr_t fnc);
void pFpppu(x86emu_t *emu, uintptr_t fnc);
void pFpppL(x86emu_t *emu, uintptr_t fnc);
@@ -756,6 +843,7 @@ void vFEpuup(x86emu_t *emu, uintptr_t fnc);
void vFEpupp(x86emu_t *emu, uintptr_t fnc);
void vFEpLLp(x86emu_t *emu, uintptr_t fnc);
void vFEppip(x86emu_t *emu, uintptr_t fnc);
void vFEppup(x86emu_t *emu, uintptr_t fnc);
void vFEpppp(x86emu_t *emu, uintptr_t fnc);
void vFiiiii(x86emu_t *emu, uintptr_t fnc);
void vFiiiiu(x86emu_t *emu, uintptr_t fnc);
@@ -819,7 +907,15 @@ void vFpuiip(x86emu_t *emu, uintptr_t fnc);
void vFpuipp(x86emu_t *emu, uintptr_t fnc);
void vFpuipV(x86emu_t *emu, uintptr_t fnc);
void vFpuuuu(x86emu_t *emu, uintptr_t fnc);
void vFpuuup(x86emu_t *emu, uintptr_t fnc);
void vFpuupp(x86emu_t *emu, uintptr_t fnc);
void vFpuddd(x86emu_t *emu, uintptr_t fnc);
void vFpupup(x86emu_t *emu, uintptr_t fnc);
void vFpUuiu(x86emu_t *emu, uintptr_t fnc);
void vFpUUuu(x86emu_t *emu, uintptr_t fnc);
void vFpUUup(x86emu_t *emu, uintptr_t fnc);
void vFpUUUu(x86emu_t *emu, uintptr_t fnc);
void vFpUUUp(x86emu_t *emu, uintptr_t fnc);
void vFpffff(x86emu_t *emu, uintptr_t fnc);
void vFpddii(x86emu_t *emu, uintptr_t fnc);
void vFpdddd(x86emu_t *emu, uintptr_t fnc);
@@ -853,6 +949,7 @@ void iFEpiup(x86emu_t *emu, uintptr_t fnc);
void iFEpipi(x86emu_t *emu, uintptr_t fnc);
void iFEpipp(x86emu_t *emu, uintptr_t fnc);
void iFEpupV(x86emu_t *emu, uintptr_t fnc);
void iFEpUup(x86emu_t *emu, uintptr_t fnc);
void iFEpLpp(x86emu_t *emu, uintptr_t fnc);
void iFEpLpV(x86emu_t *emu, uintptr_t fnc);
void iFEppii(x86emu_t *emu, uintptr_t fnc);
@@ -862,6 +959,7 @@ void iFEpplp(x86emu_t *emu, uintptr_t fnc);
void iFEpppp(x86emu_t *emu, uintptr_t fnc);
void iFEpppV(x86emu_t *emu, uintptr_t fnc);
void iFEppVV(x86emu_t *emu, uintptr_t fnc);
void iFEpPpp(x86emu_t *emu, uintptr_t fnc);
void iFiiipu(x86emu_t *emu, uintptr_t fnc);
void iFiiipp(x86emu_t *emu, uintptr_t fnc);
void iFiiupp(x86emu_t *emu, uintptr_t fnc);
@@ -892,6 +990,7 @@ void iFpipiL(x86emu_t *emu, uintptr_t fnc);
void iFpipip(x86emu_t *emu, uintptr_t fnc);
void iFpippi(x86emu_t *emu, uintptr_t fnc);
void iFpippp(x86emu_t *emu, uintptr_t fnc);
void iFpipGp(x86emu_t *emu, uintptr_t fnc);
void iFpCCCC(x86emu_t *emu, uintptr_t fnc);
void iFpuiii(x86emu_t *emu, uintptr_t fnc);
void iFpuiup(x86emu_t *emu, uintptr_t fnc);
@@ -901,6 +1000,7 @@ void iFpuuup(x86emu_t *emu, uintptr_t fnc);
void iFpuuLL(x86emu_t *emu, uintptr_t fnc);
void iFpuupu(x86emu_t *emu, uintptr_t fnc);
void iFpuupp(x86emu_t *emu, uintptr_t fnc);
void iFpupiU(x86emu_t *emu, uintptr_t fnc);
void iFpupuu(x86emu_t *emu, uintptr_t fnc);
void iFpupup(x86emu_t *emu, uintptr_t fnc);
void iFpuppu(x86emu_t *emu, uintptr_t fnc);
@@ -916,8 +1016,10 @@ void iFppipp(x86emu_t *emu, uintptr_t fnc);
void iFppupi(x86emu_t *emu, uintptr_t fnc);
void iFppupp(x86emu_t *emu, uintptr_t fnc);
void iFppllp(x86emu_t *emu, uintptr_t fnc);
void iFpplpp(x86emu_t *emu, uintptr_t fnc);
void iFppLwp(x86emu_t *emu, uintptr_t fnc);
void iFppLip(x86emu_t *emu, uintptr_t fnc);
void iFppLpi(x86emu_t *emu, uintptr_t fnc);
void iFppLpL(x86emu_t *emu, uintptr_t fnc);
void iFpppii(x86emu_t *emu, uintptr_t fnc);
void iFpppiu(x86emu_t *emu, uintptr_t fnc);
@@ -929,8 +1031,10 @@ void iFppppi(x86emu_t *emu, uintptr_t fnc);
void iFppppu(x86emu_t *emu, uintptr_t fnc);
void iFppppL(x86emu_t *emu, uintptr_t fnc);
void iFppppp(x86emu_t *emu, uintptr_t fnc);
void iFpppGp(x86emu_t *emu, uintptr_t fnc);
void IFppIII(x86emu_t *emu, uintptr_t fnc);
void uFEippp(x86emu_t *emu, uintptr_t fnc);
void uFEpipp(x86emu_t *emu, uintptr_t fnc);
void uFEppuu(x86emu_t *emu, uintptr_t fnc);
void uFEpppp(x86emu_t *emu, uintptr_t fnc);
void uFiuuuu(x86emu_t *emu, uintptr_t fnc);
@@ -952,6 +1056,7 @@ void lFppiip(x86emu_t *emu, uintptr_t fnc);
void LFEpppp(x86emu_t *emu, uintptr_t fnc);
void LFpuppi(x86emu_t *emu, uintptr_t fnc);
void LFpLppp(x86emu_t *emu, uintptr_t fnc);
void LFpppii(x86emu_t *emu, uintptr_t fnc);
void LFppppp(x86emu_t *emu, uintptr_t fnc);
void pFEpiii(x86emu_t *emu, uintptr_t fnc);
void pFEpipi(x86emu_t *emu, uintptr_t fnc);
@@ -961,8 +1066,11 @@ void pFEpupp(x86emu_t *emu, uintptr_t fnc);
void pFEppii(x86emu_t *emu, uintptr_t fnc);
void pFEppip(x86emu_t *emu, uintptr_t fnc);
void pFEppCC(x86emu_t *emu, uintptr_t fnc);
void pFEppuW(x86emu_t *emu, uintptr_t fnc);
void pFEppuu(x86emu_t *emu, uintptr_t fnc);
void pFEppup(x86emu_t *emu, uintptr_t fnc);
void pFEpppi(x86emu_t *emu, uintptr_t fnc);
void pFEpppu(x86emu_t *emu, uintptr_t fnc);
void pFEpppp(x86emu_t *emu, uintptr_t fnc);
void pFiiiii(x86emu_t *emu, uintptr_t fnc);
void pFipipu(x86emu_t *emu, uintptr_t fnc);
@@ -977,6 +1085,7 @@ void pFpiipi(x86emu_t *emu, uintptr_t fnc);
void pFpiipp(x86emu_t *emu, uintptr_t fnc);
void pFpiCCC(x86emu_t *emu, uintptr_t fnc);
void pFpiuuu(x86emu_t *emu, uintptr_t fnc);
void pFpippi(x86emu_t *emu, uintptr_t fnc);
void pFpippp(x86emu_t *emu, uintptr_t fnc);
void pFpuiii(x86emu_t *emu, uintptr_t fnc);
void pFpuuip(x86emu_t *emu, uintptr_t fnc);
@@ -1002,7 +1111,9 @@ void vFEiiipp(x86emu_t *emu, uintptr_t fnc);
void vFEpiLpp(x86emu_t *emu, uintptr_t fnc);
void vFEpippp(x86emu_t *emu, uintptr_t fnc);
void vFEpuipp(x86emu_t *emu, uintptr_t fnc);
void vFEpupup(x86emu_t *emu, uintptr_t fnc);
void vFEpLLpp(x86emu_t *emu, uintptr_t fnc);
void vFEppupp(x86emu_t *emu, uintptr_t fnc);
void vFEppppp(x86emu_t *emu, uintptr_t fnc);
void vFiiiiii(x86emu_t *emu, uintptr_t fnc);
void vFiiiuil(x86emu_t *emu, uintptr_t fnc);
@@ -1053,9 +1164,16 @@ void vFpiippp(x86emu_t *emu, uintptr_t fnc);
void vFpipiiu(x86emu_t *emu, uintptr_t fnc);
void vFpipipV(x86emu_t *emu, uintptr_t fnc);
void vFpipppi(x86emu_t *emu, uintptr_t fnc);
void vFpipppp(x86emu_t *emu, uintptr_t fnc);
void vFpuiiiu(x86emu_t *emu, uintptr_t fnc);
void vFpuiipp(x86emu_t *emu, uintptr_t fnc);
void vFpuuuiu(x86emu_t *emu, uintptr_t fnc);
void vFpuuppp(x86emu_t *emu, uintptr_t fnc);
void vFpudddd(x86emu_t *emu, uintptr_t fnc);
void vFpUiuup(x86emu_t *emu, uintptr_t fnc);
void vFpUiUup(x86emu_t *emu, uintptr_t fnc);
void vFpUipup(x86emu_t *emu, uintptr_t fnc);
void vFpUUiup(x86emu_t *emu, uintptr_t fnc);
void vFpdddii(x86emu_t *emu, uintptr_t fnc);
void vFpddddd(x86emu_t *emu, uintptr_t fnc);
void vFppiiii(x86emu_t *emu, uintptr_t fnc);
@@ -1065,11 +1183,15 @@ void vFppiipi(x86emu_t *emu, uintptr_t fnc);
void vFppiipp(x86emu_t *emu, uintptr_t fnc);
void vFppilpp(x86emu_t *emu, uintptr_t fnc);
void vFppippi(x86emu_t *emu, uintptr_t fnc);
void vFppippp(x86emu_t *emu, uintptr_t fnc);
void vFppuuuu(x86emu_t *emu, uintptr_t fnc);
void vFppupii(x86emu_t *emu, uintptr_t fnc);
void vFppuppp(x86emu_t *emu, uintptr_t fnc);
void vFppdidd(x86emu_t *emu, uintptr_t fnc);
void vFpplppi(x86emu_t *emu, uintptr_t fnc);
void vFpplppp(x86emu_t *emu, uintptr_t fnc);
void vFppLppi(x86emu_t *emu, uintptr_t fnc);
void vFppLppp(x86emu_t *emu, uintptr_t fnc);
void vFpppiii(x86emu_t *emu, uintptr_t fnc);
void vFpppiip(x86emu_t *emu, uintptr_t fnc);
void vFpppiff(x86emu_t *emu, uintptr_t fnc);
@@ -1080,6 +1202,7 @@ void vFpppppi(x86emu_t *emu, uintptr_t fnc);
void vFpppppu(x86emu_t *emu, uintptr_t fnc);
void vFpppppL(x86emu_t *emu, uintptr_t fnc);
void vFpppppp(x86emu_t *emu, uintptr_t fnc);
void cFppLppi(x86emu_t *emu, uintptr_t fnc);
void iFEiippi(x86emu_t *emu, uintptr_t fnc);
void iFEiippp(x86emu_t *emu, uintptr_t fnc);
void iFEipuup(x86emu_t *emu, uintptr_t fnc);
@@ -1093,6 +1216,7 @@ void iFEpipVV(x86emu_t *emu, uintptr_t fnc);
void iFEpuuip(x86emu_t *emu, uintptr_t fnc);
void iFEpuppp(x86emu_t *emu, uintptr_t fnc);
void iFEpupVV(x86emu_t *emu, uintptr_t fnc);
void iFEpUPpp(x86emu_t *emu, uintptr_t fnc);
void iFEpLppp(x86emu_t *emu, uintptr_t fnc);
void iFEppppp(x86emu_t *emu, uintptr_t fnc);
void iFiiiiii(x86emu_t *emu, uintptr_t fnc);
@@ -1125,6 +1249,8 @@ void iFpCpipu(x86emu_t *emu, uintptr_t fnc);
void iFpuiiii(x86emu_t *emu, uintptr_t fnc);
void iFpupipi(x86emu_t *emu, uintptr_t fnc);
void iFpupuui(x86emu_t *emu, uintptr_t fnc);
void iFpUUUip(x86emu_t *emu, uintptr_t fnc);
void iFpUUUUp(x86emu_t *emu, uintptr_t fnc);
void iFppiiip(x86emu_t *emu, uintptr_t fnc);
void iFppiiuu(x86emu_t *emu, uintptr_t fnc);
void iFppiipi(x86emu_t *emu, uintptr_t fnc);
@@ -1132,18 +1258,22 @@ void iFppiipp(x86emu_t *emu, uintptr_t fnc);
void iFppipii(x86emu_t *emu, uintptr_t fnc);
void iFppipiL(x86emu_t *emu, uintptr_t fnc);
void iFppipip(x86emu_t *emu, uintptr_t fnc);
void iFppIipp(x86emu_t *emu, uintptr_t fnc);
void iFppIppp(x86emu_t *emu, uintptr_t fnc);
void iFppuiii(x86emu_t *emu, uintptr_t fnc);
void iFppuiiu(x86emu_t *emu, uintptr_t fnc);
void iFppuipp(x86emu_t *emu, uintptr_t fnc);
void iFppuIII(x86emu_t *emu, uintptr_t fnc);
void iFppuupp(x86emu_t *emu, uintptr_t fnc);
void iFppupip(x86emu_t *emu, uintptr_t fnc);
void iFppuppp(x86emu_t *emu, uintptr_t fnc);
void iFppUipp(x86emu_t *emu, uintptr_t fnc);
void iFppUupp(x86emu_t *emu, uintptr_t fnc);
void iFppdidd(x86emu_t *emu, uintptr_t fnc);
void iFpplppi(x86emu_t *emu, uintptr_t fnc);
void iFppLupp(x86emu_t *emu, uintptr_t fnc);
void iFppLpLp(x86emu_t *emu, uintptr_t fnc);
void iFppLppp(x86emu_t *emu, uintptr_t fnc);
void iFpppiuu(x86emu_t *emu, uintptr_t fnc);
void iFpppipp(x86emu_t *emu, uintptr_t fnc);
void iFpppuii(x86emu_t *emu, uintptr_t fnc);
@@ -1156,6 +1286,7 @@ void iFpppppi(x86emu_t *emu, uintptr_t fnc);
void iFpppppu(x86emu_t *emu, uintptr_t fnc);
void iFpppppp(x86emu_t *emu, uintptr_t fnc);
void uFEiippp(x86emu_t *emu, uintptr_t fnc);
void uFEiuppp(x86emu_t *emu, uintptr_t fnc);
void uFpippup(x86emu_t *emu, uintptr_t fnc);
void uFppippp(x86emu_t *emu, uintptr_t fnc);
void uFpppppp(x86emu_t *emu, uintptr_t fnc);
@@ -1171,19 +1302,25 @@ void pFEppCWp(x86emu_t *emu, uintptr_t fnc);
void pFEppCuW(x86emu_t *emu, uintptr_t fnc);
void pFEppCuu(x86emu_t *emu, uintptr_t fnc);
void pFEppuWp(x86emu_t *emu, uintptr_t fnc);
void pFEppuuC(x86emu_t *emu, uintptr_t fnc);
void pFEppuuu(x86emu_t *emu, uintptr_t fnc);
void pFEppuup(x86emu_t *emu, uintptr_t fnc);
void pFEpppup(x86emu_t *emu, uintptr_t fnc);
void pFEppppi(x86emu_t *emu, uintptr_t fnc);
void pFEppppp(x86emu_t *emu, uintptr_t fnc);
void pFiiiiii(x86emu_t *emu, uintptr_t fnc);
void pFiCiiCi(x86emu_t *emu, uintptr_t fnc);
void pFdddddd(x86emu_t *emu, uintptr_t fnc);
void pFpiiiiu(x86emu_t *emu, uintptr_t fnc);
void pFpiiCCC(x86emu_t *emu, uintptr_t fnc);
void pFpiiuuu(x86emu_t *emu, uintptr_t fnc);
void pFpippip(x86emu_t *emu, uintptr_t fnc);
void pFpuuuuu(x86emu_t *emu, uintptr_t fnc);
void pFplpppp(x86emu_t *emu, uintptr_t fnc);
void pFppiiii(x86emu_t *emu, uintptr_t fnc);
void pFppiipp(x86emu_t *emu, uintptr_t fnc);
void pFppiCCC(x86emu_t *emu, uintptr_t fnc);
void pFppippi(x86emu_t *emu, uintptr_t fnc);
void pFppippp(x86emu_t *emu, uintptr_t fnc);
void pFpppiii(x86emu_t *emu, uintptr_t fnc);
void pFpppiui(x86emu_t *emu, uintptr_t fnc);
@@ -1193,6 +1330,8 @@ void pFpppppu(x86emu_t *emu, uintptr_t fnc);
void pFpppppp(x86emu_t *emu, uintptr_t fnc);
void pFSpiiii(x86emu_t *emu, uintptr_t fnc);
void vFEpipppp(x86emu_t *emu, uintptr_t fnc);
void vFEpuipuV(x86emu_t *emu, uintptr_t fnc);
void vFEpppppp(x86emu_t *emu, uintptr_t fnc);
void vFiiiiiip(x86emu_t *emu, uintptr_t fnc);
void vFiiiiuup(x86emu_t *emu, uintptr_t fnc);
void vFiiupuip(x86emu_t *emu, uintptr_t fnc);
@@ -1232,6 +1371,10 @@ void vFpiiiipp(x86emu_t *emu, uintptr_t fnc);
void vFpiiliip(x86emu_t *emu, uintptr_t fnc);
void vFpiipCpp(x86emu_t *emu, uintptr_t fnc);
void vFpipipii(x86emu_t *emu, uintptr_t fnc);
void vFpipppii(x86emu_t *emu, uintptr_t fnc);
void vFpuuuuuu(x86emu_t *emu, uintptr_t fnc);
void vFpuuUUuu(x86emu_t *emu, uintptr_t fnc);
void vFpUiUiup(x86emu_t *emu, uintptr_t fnc);
void vFpddiidd(x86emu_t *emu, uintptr_t fnc);
void vFpdddddd(x86emu_t *emu, uintptr_t fnc);
void vFppiiiii(x86emu_t *emu, uintptr_t fnc);
@@ -1244,15 +1387,22 @@ void vFppilppi(x86emu_t *emu, uintptr_t fnc);
void vFppipiip(x86emu_t *emu, uintptr_t fnc);
void vFppipipp(x86emu_t *emu, uintptr_t fnc);
void vFppipppp(x86emu_t *emu, uintptr_t fnc);
void vFppLpppi(x86emu_t *emu, uintptr_t fnc);
void vFppLpppp(x86emu_t *emu, uintptr_t fnc);
void vFpppiiii(x86emu_t *emu, uintptr_t fnc);
void vFpppiipi(x86emu_t *emu, uintptr_t fnc);
void vFpppiipp(x86emu_t *emu, uintptr_t fnc);
void vFpppippi(x86emu_t *emu, uintptr_t fnc);
void vFpppuuuu(x86emu_t *emu, uintptr_t fnc);
void vFppppiii(x86emu_t *emu, uintptr_t fnc);
void vFppppiip(x86emu_t *emu, uintptr_t fnc);
void vFppppipi(x86emu_t *emu, uintptr_t fnc);
void vFpppppip(x86emu_t *emu, uintptr_t fnc);
void vFppppppi(x86emu_t *emu, uintptr_t fnc);
void vFppppppp(x86emu_t *emu, uintptr_t fnc);
void iFEpuiupV(x86emu_t *emu, uintptr_t fnc);
void iFEpupppp(x86emu_t *emu, uintptr_t fnc);
void iFEpUuppp(x86emu_t *emu, uintptr_t fnc);
void iFEppiuui(x86emu_t *emu, uintptr_t fnc);
void iFEppupIi(x86emu_t *emu, uintptr_t fnc);
void iFEppuppp(x86emu_t *emu, uintptr_t fnc);
@@ -1261,6 +1411,7 @@ void iFEpppppp(x86emu_t *emu, uintptr_t fnc);
void iFiiiiiip(x86emu_t *emu, uintptr_t fnc);
void iFiuppppp(x86emu_t *emu, uintptr_t fnc);
void iFpiiiiii(x86emu_t *emu, uintptr_t fnc);
void iFpiiiiip(x86emu_t *emu, uintptr_t fnc);
void iFpiiiLwp(x86emu_t *emu, uintptr_t fnc);
void iFpiiuuiu(x86emu_t *emu, uintptr_t fnc);
void iFpiiuuuu(x86emu_t *emu, uintptr_t fnc);
@@ -1286,23 +1437,29 @@ void iFppiipii(x86emu_t *emu, uintptr_t fnc);
void iFppiipiL(x86emu_t *emu, uintptr_t fnc);
void iFppipiip(x86emu_t *emu, uintptr_t fnc);
void iFppipipi(x86emu_t *emu, uintptr_t fnc);
void iFppipipp(x86emu_t *emu, uintptr_t fnc);
void iFppippip(x86emu_t *emu, uintptr_t fnc);
void iFppipppi(x86emu_t *emu, uintptr_t fnc);
void iFppipppp(x86emu_t *emu, uintptr_t fnc);
void iFppuipiL(x86emu_t *emu, uintptr_t fnc);
void iFppLiipp(x86emu_t *emu, uintptr_t fnc);
void iFpppiiii(x86emu_t *emu, uintptr_t fnc);
void iFpppiiuu(x86emu_t *emu, uintptr_t fnc);
void iFpppiiup(x86emu_t *emu, uintptr_t fnc);
void iFpppiipi(x86emu_t *emu, uintptr_t fnc);
void iFpppiuwu(x86emu_t *emu, uintptr_t fnc);
void iFpppippi(x86emu_t *emu, uintptr_t fnc);
void iFpppippp(x86emu_t *emu, uintptr_t fnc);
void iFpppuiii(x86emu_t *emu, uintptr_t fnc);
void iFpppuppp(x86emu_t *emu, uintptr_t fnc);
void iFppppiii(x86emu_t *emu, uintptr_t fnc);
void iFppppipp(x86emu_t *emu, uintptr_t fnc);
void iFppppdpi(x86emu_t *emu, uintptr_t fnc);
void iFpppppip(x86emu_t *emu, uintptr_t fnc);
void iFpppppup(x86emu_t *emu, uintptr_t fnc);
void iFppppppi(x86emu_t *emu, uintptr_t fnc);
void iFppppppp(x86emu_t *emu, uintptr_t fnc);
void uFEpiippp(x86emu_t *emu, uintptr_t fnc);
void uFuippppp(x86emu_t *emu, uintptr_t fnc);
void LFEpppppu(x86emu_t *emu, uintptr_t fnc);
void pFEpLiiii(x86emu_t *emu, uintptr_t fnc);
@@ -1319,9 +1476,13 @@ void pFifffppp(x86emu_t *emu, uintptr_t fnc);
void pFuupupup(x86emu_t *emu, uintptr_t fnc);
void pFplppppp(x86emu_t *emu, uintptr_t fnc);
void pFppiiipp(x86emu_t *emu, uintptr_t fnc);
void pFppiiCCC(x86emu_t *emu, uintptr_t fnc);
void pFppiippp(x86emu_t *emu, uintptr_t fnc);
void pFppipipp(x86emu_t *emu, uintptr_t fnc);
void pFppuuuuu(x86emu_t *emu, uintptr_t fnc);
void pFppuuppp(x86emu_t *emu, uintptr_t fnc);
void pFppLiiip(x86emu_t *emu, uintptr_t fnc);
void pFppLipip(x86emu_t *emu, uintptr_t fnc);
void pFpppccci(x86emu_t *emu, uintptr_t fnc);
void pFpppiiii(x86emu_t *emu, uintptr_t fnc);
void pFpppiipp(x86emu_t *emu, uintptr_t fnc);
@@ -1336,6 +1497,7 @@ void pFpppllli(x86emu_t *emu, uintptr_t fnc);
void pFpppLLLi(x86emu_t *emu, uintptr_t fnc);
void pFppppuuu(x86emu_t *emu, uintptr_t fnc);
void pFpppppuu(x86emu_t *emu, uintptr_t fnc);
void pFppppppi(x86emu_t *emu, uintptr_t fnc);
void pFppppppp(x86emu_t *emu, uintptr_t fnc);
void vFEiippppV(x86emu_t *emu, uintptr_t fnc);
void vFEiupippp(x86emu_t *emu, uintptr_t fnc);
@@ -1366,10 +1528,15 @@ void vFuuuuufff(x86emu_t *emu, uintptr_t fnc);
void vFffffffff(x86emu_t *emu, uintptr_t fnc);
void vFpiiiiiii(x86emu_t *emu, uintptr_t fnc);
void vFpiiiipii(x86emu_t *emu, uintptr_t fnc);
void vFpiiULipp(x86emu_t *emu, uintptr_t fnc);
void vFpiUuupup(x86emu_t *emu, uintptr_t fnc);
void vFpippiiuu(x86emu_t *emu, uintptr_t fnc);
void vFpippiipi(x86emu_t *emu, uintptr_t fnc);
void vFpUiUiupi(x86emu_t *emu, uintptr_t fnc);
void vFpUuuUUUi(x86emu_t *emu, uintptr_t fnc);
void vFppiiiiii(x86emu_t *emu, uintptr_t fnc);
void vFppiiipii(x86emu_t *emu, uintptr_t fnc);
void vFppipipii(x86emu_t *emu, uintptr_t fnc);
void vFppipppui(x86emu_t *emu, uintptr_t fnc);
void vFppippppi(x86emu_t *emu, uintptr_t fnc);
void vFppippppp(x86emu_t *emu, uintptr_t fnc);
@@ -1395,12 +1562,16 @@ void iFpuipuppp(x86emu_t *emu, uintptr_t fnc);
void iFpuippupp(x86emu_t *emu, uintptr_t fnc);
void iFpuuiiiii(x86emu_t *emu, uintptr_t fnc);
void iFpupppppp(x86emu_t *emu, uintptr_t fnc);
void iFpUuuLpUi(x86emu_t *emu, uintptr_t fnc);
void iFppiiiiiu(x86emu_t *emu, uintptr_t fnc);
void iFppIIIppp(x86emu_t *emu, uintptr_t fnc);
void iFpppiippp(x86emu_t *emu, uintptr_t fnc);
void iFpppipipi(x86emu_t *emu, uintptr_t fnc);
void iFpppipppp(x86emu_t *emu, uintptr_t fnc);
void iFppppiipi(x86emu_t *emu, uintptr_t fnc);
void iFppppippp(x86emu_t *emu, uintptr_t fnc);
void iFppppppii(x86emu_t *emu, uintptr_t fnc);
void iFpppppppi(x86emu_t *emu, uintptr_t fnc);
void iFpppppppp(x86emu_t *emu, uintptr_t fnc);
void uFEipipppp(x86emu_t *emu, uintptr_t fnc);
void uFEpiupppp(x86emu_t *emu, uintptr_t fnc);
@@ -1411,6 +1582,7 @@ void LFEpiupppp(x86emu_t *emu, uintptr_t fnc);
void pFEppCuuCC(x86emu_t *emu, uintptr_t fnc);
void pFEppCuuWW(x86emu_t *emu, uintptr_t fnc);
void pFEppCuuup(x86emu_t *emu, uintptr_t fnc);
void pFEppuuwwu(x86emu_t *emu, uintptr_t fnc);
void pFEppuuuuu(x86emu_t *emu, uintptr_t fnc);
void pFEppuuUUU(x86emu_t *emu, uintptr_t fnc);
void pFEppLiiip(x86emu_t *emu, uintptr_t fnc);
@@ -1425,11 +1597,13 @@ void pFpiiiiiuu(x86emu_t *emu, uintptr_t fnc);
void pFpipppppp(x86emu_t *emu, uintptr_t fnc);
void pFpWWiCpup(x86emu_t *emu, uintptr_t fnc);
void pFpuuuupup(x86emu_t *emu, uintptr_t fnc);
void pFpupupuuu(x86emu_t *emu, uintptr_t fnc);
void pFpdwwWWui(x86emu_t *emu, uintptr_t fnc);
void pFplpppppp(x86emu_t *emu, uintptr_t fnc);
void pFppiiiiii(x86emu_t *emu, uintptr_t fnc);
void pFpppuuuuu(x86emu_t *emu, uintptr_t fnc);
void pFpppppupp(x86emu_t *emu, uintptr_t fnc);
void vFEpiiiiipp(x86emu_t *emu, uintptr_t fnc);
void vFEppiipppp(x86emu_t *emu, uintptr_t fnc);
void vFEpppiippp(x86emu_t *emu, uintptr_t fnc);
void vFuiiiiiiii(x86emu_t *emu, uintptr_t fnc);
@@ -1458,6 +1632,7 @@ void vFppipppiip(x86emu_t *emu, uintptr_t fnc);
void vFppuuiiiii(x86emu_t *emu, uintptr_t fnc);
void vFpplpppppi(x86emu_t *emu, uintptr_t fnc);
void vFpppiiiiii(x86emu_t *emu, uintptr_t fnc);
void vFppppipiip(x86emu_t *emu, uintptr_t fnc);
void vFpppppippp(x86emu_t *emu, uintptr_t fnc);
void vFppppppppp(x86emu_t *emu, uintptr_t fnc);
void iFEiiuuuuuu(x86emu_t *emu, uintptr_t fnc);
@@ -1465,6 +1640,7 @@ void iFEpiiiiipi(x86emu_t *emu, uintptr_t fnc);
void iFEpuuiippu(x86emu_t *emu, uintptr_t fnc);
void iFEpuuuiipp(x86emu_t *emu, uintptr_t fnc);
void iFEpppipppp(x86emu_t *emu, uintptr_t fnc);
void iFEpppppupp(x86emu_t *emu, uintptr_t fnc);
void iFiiiiiiiip(x86emu_t *emu, uintptr_t fnc);
void iFiiiipiiip(x86emu_t *emu, uintptr_t fnc);
void iFipiipippi(x86emu_t *emu, uintptr_t fnc);
@@ -1477,6 +1653,7 @@ void iFpLLLLLLLL(x86emu_t *emu, uintptr_t fnc);
void iFppiiiiiii(x86emu_t *emu, uintptr_t fnc);
void iFppiuiippu(x86emu_t *emu, uintptr_t fnc);
void iFppipiiipi(x86emu_t *emu, uintptr_t fnc);
void iFppLpiippp(x86emu_t *emu, uintptr_t fnc);
void iFpppiiuuii(x86emu_t *emu, uintptr_t fnc);
void iFpppiipiiu(x86emu_t *emu, uintptr_t fnc);
void iFppppupiii(x86emu_t *emu, uintptr_t fnc);
@@ -1487,9 +1664,11 @@ void uFppppppppp(x86emu_t *emu, uintptr_t fnc);
void LFEppppppii(x86emu_t *emu, uintptr_t fnc);
void pFEppiiuuui(x86emu_t *emu, uintptr_t fnc);
void pFEppCuwwWW(x86emu_t *emu, uintptr_t fnc);
void pFEppCuWCCC(x86emu_t *emu, uintptr_t fnc);
void pFEppCuuwwp(x86emu_t *emu, uintptr_t fnc);
void pFEppCuuuuu(x86emu_t *emu, uintptr_t fnc);
void pFEppuippuu(x86emu_t *emu, uintptr_t fnc);
void pFEppuuuwwu(x86emu_t *emu, uintptr_t fnc);
void pFEppuupwwC(x86emu_t *emu, uintptr_t fnc);
void pFEpppppiiV(x86emu_t *emu, uintptr_t fnc);
void pFEpppppppi(x86emu_t *emu, uintptr_t fnc);
@@ -1501,6 +1680,7 @@ void pFppiiuuuuu(x86emu_t *emu, uintptr_t fnc);
void pFppipppppp(x86emu_t *emu, uintptr_t fnc);
void pFpppiiiiii(x86emu_t *emu, uintptr_t fnc);
void pFpppiipppp(x86emu_t *emu, uintptr_t fnc);
void pFpppppiipp(x86emu_t *emu, uintptr_t fnc);
void vFEiippppppp(x86emu_t *emu, uintptr_t fnc);
void vFEpippppppp(x86emu_t *emu, uintptr_t fnc);
void vFEpppiipppp(x86emu_t *emu, uintptr_t fnc);
@@ -1536,6 +1716,7 @@ void iFEpuuuuiipp(x86emu_t *emu, uintptr_t fnc);
void iFiiiiiiiiip(x86emu_t *emu, uintptr_t fnc);
void iFpuipuppppp(x86emu_t *emu, uintptr_t fnc);
void iFpuupiuiipp(x86emu_t *emu, uintptr_t fnc);
void iFppipiippii(x86emu_t *emu, uintptr_t fnc);
void iFppuuiiiiii(x86emu_t *emu, uintptr_t fnc);
void iFppuuiiuupi(x86emu_t *emu, uintptr_t fnc);
void iFpppLLipppp(x86emu_t *emu, uintptr_t fnc);
@@ -1544,10 +1725,13 @@ void uFpppppppppp(x86emu_t *emu, uintptr_t fnc);
void pFEiippppppp(x86emu_t *emu, uintptr_t fnc);
void pFEpiiiiiipp(x86emu_t *emu, uintptr_t fnc);
void pFEpippppppp(x86emu_t *emu, uintptr_t fnc);
void pFEppCCuuwwC(x86emu_t *emu, uintptr_t fnc);
void pFEppCuwwWWu(x86emu_t *emu, uintptr_t fnc);
void pFEppCuuuCup(x86emu_t *emu, uintptr_t fnc);
void pFEppuuWWCuu(x86emu_t *emu, uintptr_t fnc);
void pFplllllllll(x86emu_t *emu, uintptr_t fnc);
void pFppuiipuuii(x86emu_t *emu, uintptr_t fnc);
void vFEpiiiupupup(x86emu_t *emu, uintptr_t fnc);
void vFiippppppppp(x86emu_t *emu, uintptr_t fnc);
void vFuiiiiiiiiip(x86emu_t *emu, uintptr_t fnc);
void vFuiiiiiiiuip(x86emu_t *emu, uintptr_t fnc);
@@ -1561,6 +1745,7 @@ void vFuuddiiddiip(x86emu_t *emu, uintptr_t fnc);
void vFuffffffffff(x86emu_t *emu, uintptr_t fnc);
void vFpipipiipiii(x86emu_t *emu, uintptr_t fnc);
void vFpipppiiiipi(x86emu_t *emu, uintptr_t fnc);
void vFpupiiuPuPuP(x86emu_t *emu, uintptr_t fnc);
void vFppiiiiiiiii(x86emu_t *emu, uintptr_t fnc);
void vFppiiiiipiii(x86emu_t *emu, uintptr_t fnc);
void vFppiiiiddddi(x86emu_t *emu, uintptr_t fnc);
@@ -1575,6 +1760,7 @@ void iFEpppipppppp(x86emu_t *emu, uintptr_t fnc);
void iFEppppiiiiuu(x86emu_t *emu, uintptr_t fnc);
void iFiiiiiiiiiip(x86emu_t *emu, uintptr_t fnc);
void iFpipllippppp(x86emu_t *emu, uintptr_t fnc);
void iFppippipppip(x86emu_t *emu, uintptr_t fnc);
void iFppppiiuuiiu(x86emu_t *emu, uintptr_t fnc);
void uFEpiiupppiuV(x86emu_t *emu, uintptr_t fnc);
void uFEpiippppiup(x86emu_t *emu, uintptr_t fnc);
@@ -1605,6 +1791,8 @@ void iFpppllipppppp(x86emu_t *emu, uintptr_t fnc);
void iFpppppppppppp(x86emu_t *emu, uintptr_t fnc);
void lFpLpppppppppp(x86emu_t *emu, uintptr_t fnc);
void pFEppiiuuuipii(x86emu_t *emu, uintptr_t fnc);
void pFEppCuWCCuuCW(x86emu_t *emu, uintptr_t fnc);
void pFEppuwwWWuCuu(x86emu_t *emu, uintptr_t fnc);
void pFEppuuuwwwwWW(x86emu_t *emu, uintptr_t fnc);
void pFEppuuuWWWCCi(x86emu_t *emu, uintptr_t fnc);
void pFWWiCCCCiipup(x86emu_t *emu, uintptr_t fnc);
@@ -1657,12 +1845,15 @@ void iFpppippppppppppppp(x86emu_t *emu, uintptr_t fnc);
void pFppippipipipipipip(x86emu_t *emu, uintptr_t fnc);
void vFppuiiiiipuiiiiiiii(x86emu_t *emu, uintptr_t fnc);
void vFpppipppppppppppppp(x86emu_t *emu, uintptr_t fnc);
void LFpppppppppppppppppp(x86emu_t *emu, uintptr_t fnc);
void pFEppuuWWWWWWwwCCCuu(x86emu_t *emu, uintptr_t fnc);
void pFippppppppppppppppp(x86emu_t *emu, uintptr_t fnc);
void vFpiiiiiiiiiiiiiiiiii(x86emu_t *emu, uintptr_t fnc);
void iFpppippppppppppppppp(x86emu_t *emu, uintptr_t fnc);
void pFEppuuuuuwwuuuuUUUup(x86emu_t *emu, uintptr_t fnc);
void pFiiiippppppppppppppp(x86emu_t *emu, uintptr_t fnc);
void pFipppppppppppppppppppppp(x86emu_t *emu, uintptr_t fnc);
void iFpppppppppppppppppppppppppppppppppp(x86emu_t *emu, uintptr_t fnc);
#if defined(NOALIGN)
void IFpi(x86emu_t *emu, uintptr_t fnc);
+5
View File
@@ -6,6 +6,7 @@
#include "wrappedlibs.h"
#include "debug.h"
#include "wrapper.h"
#include "bridge.h"
#include "librarian/library_private.h"
@@ -14,6 +15,10 @@
const char* appindicatorName = "libappindicator.so.1";
#define LIBNAME appindicator
#define PRE_INIT \
if(box86_nogtk) \
return -1;
#define CUSTOM_INIT \
lib->priv.w.needed = 2; \
lib->priv.w.neededlibs = (char**)calloc(lib->priv.w.needed, sizeof(char*)); \
+2 -2
View File
@@ -19,8 +19,8 @@ GO(app_indicator_get_secondary_activate_target, pFp)
GO(app_indicator_get_status, iFp)
GO(app_indicator_get_title, pFp)
GO(app_indicator_get_type, iFv)
GO(app_indicator_new, pFp)
GO(app_indicator_new_with_path, pFp)
GO(app_indicator_new, pFppi)
GO(app_indicator_new_with_path, pFppip)
GO(app_indicator_set_attention_icon, vFpp)
GO(app_indicator_set_attention_icon_full, vFppp)
GO(app_indicator_set_icon, vFpp)
+5
View File
@@ -6,6 +6,7 @@
#include "wrappedlibs.h"
#include "debug.h"
#include "wrapper.h"
#include "bridge.h"
#include "librarian/library_private.h"
@@ -14,4 +15,8 @@
const char* atkName = "libatk-1.0.so.0";
#define LIBNAME atk
#define PRE_INIT \
if(box86_nogtk) \
return -1;
#include "wrappedlib_init.h"
+4 -4
View File
@@ -48,7 +48,7 @@ GO(atk_coord_type_get_type, iFv)
//GO(atk_focus_tracker_init,
//GO(atk_focus_tracker_notify,
//GO(atk_get_binary_age,
//GO(atk_get_default_registry,
GO(atk_get_default_registry, pFv)
//GO(atk_get_focus_object,
//GO(atk_get_interface_age,
//GO(atk_get_major_version,
@@ -131,10 +131,10 @@ GO(atk_object_set_role, vFpi)
//GO(atk_plug_get_type,
//GO(atk_plug_new,
//GO(atk_rectangle_get_type,
//GO(atk_registry_get_factory,
//GO(atk_registry_get_factory_type,
GO(atk_registry_get_factory, pFpi)
GO(atk_registry_get_factory_type, iFpi)
//GO(atk_registry_get_type,
//GO(atk_registry_set_factory_type,
GO(atk_registry_set_factory_type, vFpii)
//GO(atk_relation_add_target,
//GO(atk_relation_get_relation_type,
//GO(atk_relation_get_target,
+86 -37
View File
@@ -20,6 +20,7 @@
const char* bz2Name = "libbz2.so.1";
#define LIBNAME bz2
static library_t* my_lib = NULL;
typedef int (*iFp_t)(void*);
typedef int (*iFpi_t)(void*, int);
@@ -56,6 +57,79 @@ void freeBz2My(void* lib)
//bz2_my_t *my = (bz2_my_t *)lib;
}
#define SUPER() \
GO(0) \
GO(1) \
GO(2) \
GO(3) \
GO(4)
// alloc ...
#define GO(A) \
static uintptr_t my_alloc_fct_##A = 0; \
static void* my_alloc_##A(void* opaque, int m, int n) \
{ \
return (void*)RunFunction(my_context, my_alloc_fct_##A, 3, opaque, m, n); \
}
SUPER()
#undef GO
static void* find_alloc_Fct(void* fct)
{
if(!fct) return fct;
if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
#define GO(A) if(my_alloc_fct_##A == (uintptr_t)fct) return my_alloc_##A;
SUPER()
#undef GO
#define GO(A) if(my_alloc_fct_##A == 0) {my_alloc_fct_##A = (uintptr_t)fct; return my_alloc_##A; }
SUPER()
#undef GO
printf_log(LOG_NONE, "Warning, no more slot for bz2 alloc callback\n");
return NULL;
}
static void* reverse_alloc_Fct(void* fct)
{
if(!fct) return fct;
if(CheckBridged(my_lib->priv.w.bridge, fct))
return (void*)CheckBridged(my_lib->priv.w.bridge, fct);
#define GO(A) if(my_alloc_##A == fct) return (void*)my_alloc_fct_##A;
SUPER()
#undef GO
return (void*)AddBridge(my_lib->priv.w.bridge, my_lib->context, pFpii, fct, 0);
}
// free ...
#define GO(A) \
static uintptr_t my_free_fct_##A = 0; \
static void my_free_##A(void* opaque, void* p) \
{ \
RunFunction(my_context, my_free_fct_##A, 2, opaque, p); \
}
SUPER()
#undef GO
static void* find_free_Fct(void* fct)
{
if(!fct) return fct;
if(GetNativeFnc((uintptr_t)fct)) return GetNativeFnc((uintptr_t)fct);
#define GO(A) if(my_free_fct_##A == (uintptr_t)fct) return my_free_##A;
SUPER()
#undef GO
#define GO(A) if(my_free_fct_##A == 0) {my_free_fct_##A = (uintptr_t)fct; return my_free_##A; }
SUPER()
#undef GO
printf_log(LOG_NONE, "Warning, no more slot for bz2 free callback\n");
return NULL;
}
static void* reverse_free_Fct(void* fct)
{
if(!fct) return fct;
if(CheckBridged(my_lib->priv.w.bridge, fct))
return (void*)CheckBridged(my_lib->priv.w.bridge, fct);
#define GO(A) if(my_free_##A == fct) return (void*)my_free_fct_##A;
SUPER()
#undef GO
return (void*)AddBridge(my_lib->priv.w.bridge, my_lib->context, vFpp, fct, 0);
}
#undef SUPER
typedef struct {
char *next_in;
unsigned int avail_in;
@@ -74,41 +148,14 @@ typedef struct {
void *opaque;
} my_bz_stream_t;
static void* my_bz_malloc(void* opaque, int m, int n)
{
x86emu_t* emu = (x86emu_t*)opaque;
SetCallbackArg(emu, 0, GetCallbackArg(emu, 3));
SetCallbackArg(emu, 1, (void*)m);
SetCallbackArg(emu, 2, (void*)n);
SetCallbackNArg(emu, 3);
SetCallbackAddress(emu, (uintptr_t)GetCallbackArg(emu, 4));
return (void*)RunCallback(emu);
}
static void my_bz_free(void* opaque, void* p)
{
x86emu_t* emu = (x86emu_t*)opaque;
SetCallbackArg(emu, 0, GetCallbackArg(emu, 3));
SetCallbackArg(emu, 1, p);
SetCallbackNArg(emu, 2);
SetCallbackAddress(emu, (uintptr_t)GetCallbackArg(emu, 5));
RunCallback(emu);
}
#define WRAP_BZ(A) if(A->bzalloc || A->bzfree) { \
x86emu_t* cb = AddSharedCallback(emu, 0, 0, NULL, NULL, NULL, NULL); \
SetCallbackArg(cb, 3, A->opaque); \
SetCallbackArg(cb, 4, A->bzalloc); \
SetCallbackArg(cb, 5, A->bzfree); \
if(A->bzalloc) A->bzalloc = my_bz_malloc; \
if(A->bzfree) A->bzfree = my_bz_free; \
}
#define UNWRAP_BZ(A) if(A->bzalloc || A->bzfree) { \
x86emu_t* cb = (x86emu_t*)A->opaque;\
A->opaque = GetCallbackArg(cb, 3); \
A->bzalloc = GetCallbackArg(cb, 4); \
A->bzfree = GetCallbackArg(cb, 5); \
FreeCallback(cb); \
}
#define WRAP_BZ(A) \
A->bzalloc = find_alloc_Fct(A->bzalloc); \
A->bzfree = find_free_Fct(A->bzfree);
#define UNWRAP_BZ(A) if(A->bzalloc || A->bzfree) \
A->bzalloc = reverse_alloc_Fct(A->bzalloc); \
A->bzfree = reverse_free_Fct(A->bzfree);
EXPORT int my_BZ2_bzCompressInit(x86emu_t* emu, my_bz_stream_t* strm, int blocksize, int verbosity, int work)
{
@@ -171,11 +218,13 @@ EXPORT int my_BZ2_bzDecompressEnd(x86emu_t* emu, my_bz_stream_t* strm)
}
#define CUSTOM_INIT \
lib->priv.w.p2 = getBz2My(lib);
lib->priv.w.p2 = getBz2My(lib); \
my_lib = lib;
#define CUSTOM_FINI \
freeBz2My(lib->priv.w.p2); \
free(lib->priv.w.p2);
freeBz2My(lib->priv.w.p2); \
free(lib->priv.w.p2); \
my_lib = NULL;
#include "wrappedlib_init.h"
+1
View File
@@ -6,6 +6,7 @@
#include "wrappedlibs.h"
#include "debug.h"
#include "wrapper.h"
#include "bridge.h"
#include "librarian/library_private.h"
+32 -32
View File
@@ -40,7 +40,7 @@ GO(cairo_device_to_user_distance, vFppp)
GO(cairo_fill, vFp)
GO(cairo_fill_extents, vFppppp)
GO(cairo_fill_preserve, vFp)
//GO(cairo_font_extents,
GO(cairo_font_extents, vFpp)
//GO(cairo_font_face_destroy,
//GO(cairo_font_face_get_reference_count,
//GO(cairo_font_face_get_type,
@@ -64,22 +64,22 @@ GO(cairo_font_options_set_hint_style, vFpi)
GO(cairo_font_options_set_subpixel_order, vFpi)
GO(cairo_font_options_status, iFp)
GO(cairo_format_stride_for_width, iFii)
//GO(cairo_ft_font_face_create_for_ft_face,
//GO(cairo_ft_font_face_create_for_pattern,
//GO(cairo_ft_font_face_get_synthesize,
//GO(cairo_ft_font_face_set_synthesize,
//GO(cairo_ft_font_face_unset_synthesize,
//GO(cairo_ft_font_options_substitute,
//GO(cairo_ft_scaled_font_lock_face,
//GO(cairo_ft_scaled_font_unlock_face,
GO(cairo_ft_font_face_create_for_ft_face, pFpi)
GO(cairo_ft_font_face_create_for_pattern, pFp)
GO(cairo_ft_font_face_get_synthesize, uFp)
GO(cairo_ft_font_face_set_synthesize, vFpu)
GO(cairo_ft_font_face_unset_synthesize, vFpu)
GO(cairo_ft_font_options_substitute, vFpp)
GO(cairo_ft_scaled_font_lock_face, pFp)
GO(cairo_ft_scaled_font_unlock_face, vFp)
GO(cairo_get_antialias, iFp)
GO(cairo_get_current_point, vFppp)
GO(cairo_get_dash, vFppp)
GO(cairo_get_dash_count, iFp)
GO(cairo_get_fill_rule, iFp)
//GO(cairo_get_font_face,
//GO(cairo_get_font_matrix,
//GO(cairo_get_font_options,
GO(cairo_get_font_face, pFp)
GO(cairo_get_font_matrix, vFpp)
GO(cairo_get_font_options, vFpp)
GO(cairo_get_group_target, pFp)
GO(cairo_get_line_cap, iFp)
GO(cairo_get_line_join, iFp)
@@ -88,14 +88,14 @@ GO(cairo_get_matrix, vFpp)
GO(cairo_get_miter_limit, dFp)
GO(cairo_get_operator, iFp)
GO(cairo_get_reference_count, uFp)
//GO(cairo_get_scaled_font,
GO(cairo_get_scaled_font, pFp)
GO(cairo_get_source, pFp)
GO(cairo_get_target, pFp)
GO(cairo_get_tolerance, dFp)
GO(cairo_get_user_data, pFpp)
//GO(cairo_glyph_allocate,
//GO(cairo_glyph_extents,
//GO(cairo_glyph_free,
GO(cairo_glyph_allocate, pFi)
GO(cairo_glyph_extents, vFppip)
GO(cairo_glyph_free, vFp)
GO(cairo_glyph_path, vFppi)
GO(cairo_has_current_point, iFp)
GO(cairo_identity_matrix, vFp)
@@ -266,31 +266,31 @@ GO(cairo_scale, vFpdd)
//GO(cairo_script_surface_create,
//GO(cairo_script_surface_create_for_target,
//GO(cairo_script_write_comment,
//GO(cairo_select_font_face,
GO(cairo_select_font_face, vFppii)
GO(cairo_set_antialias, vFpi)
GO(cairo_set_dash, vFppid)
GO(cairo_set_fill_rule, vFpi)
//GO(cairo_set_font_face,
//GO(cairo_set_font_matrix,
//GO(cairo_set_font_options,
//GO(cairo_set_font_size,
GO(cairo_set_font_face, vFpp)
GO(cairo_set_font_matrix, vFpp)
GO(cairo_set_font_options, vFpp)
GO(cairo_set_font_size, vFpd)
GO(cairo_set_line_cap, vFpi)
GO(cairo_set_line_join, vFpi)
GO(cairo_set_line_width, vFpd)
GO(cairo_set_matrix, vFpp)
GO(cairo_set_miter_limit, vFpd)
GO(cairo_set_operator, vFpi)
//GO(cairo_set_scaled_font,
GO(cairo_set_scaled_font, vFpp)
GO(cairo_set_source, vFpp)
GO(cairo_set_source_rgb, vFpddd)
GO(cairo_set_source_rgba, vFpdddd)
GO(cairo_set_source_surface, vFppdd)
GO(cairo_set_tolerance, vFpd)
//GOM(cairo_set_user_data, iFEpppp)
//GO(cairo_show_glyphs,
GO(cairo_show_glyphs, vFppi)
GO(cairo_show_page, vFp)
//GO(cairo_show_text,
//GO(cairo_show_text_glyphs,
GO(cairo_show_text, vFpp)
GO(cairo_show_text_glyphs, vFppipipii)
GO(cairo_status, iFp)
//GO(cairo_status_to_string,
GO(cairo_stroke, vFp)
@@ -344,14 +344,14 @@ GO(cairo_surface_unmap_image, vFpp)
//GO(cairo_svg_surface_create_for_stream,
//GO(cairo_svg_surface_restrict_to_version,
//GO(cairo_svg_version_to_string,
//GO(cairo_text_cluster_allocate,
//GO(cairo_text_cluster_free,
//GO(cairo_text_extents,
GO(cairo_text_cluster_allocate, pFi)
GO(cairo_text_cluster_free, vFp)
GO(cairo_text_extents, vFppp)
GO(cairo_text_path, vFpp)
//GO(cairo_toy_font_face_create,
//GO(cairo_toy_font_face_get_family,
//GO(cairo_toy_font_face_get_slant,
//GO(cairo_toy_font_face_get_weight,
GO(cairo_toy_font_face_create, pFpii)
GO(cairo_toy_font_face_get_family, pFp)
GO(cairo_toy_font_face_get_slant, iFp)
GO(cairo_toy_font_face_get_weight, iFp)
GO(cairo_transform, vFpp)
GO(cairo_translate, vFpdd)
//GO(cairo_user_font_face_create,
Loaded 100 of 203 files, more files were not shown because too many files have changed in this diff. Show more