Compare commits

...
104 Commits
Author SHA1 Message Date
ptitSeb fe90260cee Made protect tracking in a single thread, and use a mailbox message system to avoid the use of lock 2021-11-04 14:04:35 +01:00
ptitSeb 841003bc47 Added 1 wrapped function to freetype (for SOR4) 2021-11-02 22:21:36 +01:00
ptitSeb 27cf5c81b2 Better wrapping for libz inflate 2021-11-02 22:08:43 +01:00
ptitSeb 323783bf49 [DYNAREC] Fixed right shift emmiter with const = 1 (help wine 6.17, and probably many other stuffs) 2021-11-01 13:20:32 +01:00
ptitSeb fbd9604dc1 Added handling of ARCH_GET_FS to arch_prctl 2021-11-01 13:19:44 +01:00
ptitSeb 5494d417c0 [DEBUG] Don't overwrite trace if %pid is used 2021-11-01 11:28:17 +01:00
ptitSeb 472037cba2 [ARM64] Check if Atomics are supported (not used yet) 2021-11-01 11:27:36 +01:00
ptitSeb 1b19d8b909 Added Phytium paragraph to COMPILE.md 2021-10-30 12:12:13 +02:00
ptitSeb c2909c32ab Updated the CHANGELOG 2021-10-27 19:42:19 +02:00
ptitSeb a7c0c01bf4 [DYNAREC] Cancel a dynablock if a segfault occurs while building it 2021-10-27 19:42:01 +02:00
ptitSeb d80226ec61 Added signalfd wrapped function to libc 2021-10-26 20:10:29 +02:00
ptitSeb da81ba5be8 Fixed some program (like the one made in rust) that was getting the command line properly 2021-10-26 19:03:03 +02:00
ptitSeb f81874277c Added reboot wrapped function to libc 2021-10-26 18:30:38 +02:00
ptitSeb d93b97ee92 Added a bunch of aio_ and mq_ wrapped function to librt 2021-10-26 17:45:24 +02:00
ptitSeb 4812d20da5 Added mogery to major code contributor in chinese Readme too 2021-10-25 09:34:47 +02:00
ptitSeb 734e7cd47c Added @mogery to major code contributor 2021-10-25 09:34:12 +02:00
ptitSeb d052b35c40 Detect steamwebhelper and don't load it for now (until it's actually fixed) 2021-10-24 19:07:55 +02:00
ptitSeb 2bd3a3ccfa Optimized (and small fixes) to custom allocator ([DYNAREC] Speedup long launch time) 2021-10-24 19:06:23 +02:00
ptitSeb 1886c454ca Added 67 0F 67/7F ocpodes ([DYNAREC] too) (for The Last Federation) 2021-10-24 18:12:37 +02:00
ptitSeb 91ee1afe24 Added wrapped libncursesw.so.6 (for #148) 2021-10-23 19:02:49 +02:00
ptitSeb d867f578df Fixed SDL_Log wrapped function 2021-10-23 15:50:41 +02:00
ptitSeb b48ba048ed Added FcConfigAppFontAddDir wrapped function (for #150) 2021-10-22 20:54:37 +02:00
ptitSeb 35a21d8932 Merge pull request #147 from bbbruni/main
Add a debug mode compilation with disabled compiler optimizations
2021-10-21 22:14:19 +02:00
bbbruni 81ec174e2a Added PKGBUILD-x86_64-DEBUG 2021-10-21 22:47:08 +03:00
bbbruni 400ea800d9 Added PKGBUILD-tegra-DEBUG 2021-10-21 22:45:44 +03:00
bbbruni 0e1215268a Added PKGBUILD-rpi4-DEBUG 2021-10-21 22:44:24 +03:00
bbbruni a72d257443 Added PKGBUILD-rk3399-DEBUG 2021-10-21 22:42:28 +03:00
bbbruni 6a99a4b359 Changed DCMAKE_BUILD_TYPE to Debug 2021-10-21 22:40:57 +03:00
bbbruni b6764d1d6f Add debug version of PKGBUILD-arm64 2021-10-21 22:37:11 +03:00
bbbruni d5e105ce62 Disable compiler optimizations in debug mode 2021-10-21 22:31:50 +03:00
ptitSeb 45ee1e3c3c Added a new wrapped function to libc (for #143) 2021-10-21 19:31:33 +02:00
ptitSeb b1d0dde0b4 Proper fix for link issue on glibc 2.34+ (for #120) 2021-10-20 22:54:42 +02:00
ptitSeb cb06d28383 Added explicit link with libc (might help with #120) 2021-10-20 10:40:29 +02:00
ptitSeb 36bfcd21d4 Merge pull request #135 from mogery/getattr-align-wrap
Add alignment wrapper to pthread_getattr_np.
2021-10-18 10:12:48 +02:00
ptitSeb faa48276e5 Merge pull request #137 from Heasterian/patch-2
Fixing typo
2021-10-18 07:43:21 +02:00
ptitSeb 8e5d32430a Fixed build 2021-10-17 23:06:01 +02:00
Heasterian ac2d5b17dd Fixing typo 2021-10-17 23:59:46 +03:00
ptitSeb 0e2c63d9fb Merge pull request #136 from Heasterian/patch-1
Add Snapdragon 845 compilation
2021-10-17 22:21:33 +02:00
Heasterian 71b446774c Update COMPILE.md
Changes about compilation on Snapdragon 845 devices
2021-10-17 22:34:47 +03:00
Heasterian dac71e9f7b Update CMakeLists.txt
Adding configuration for Snapdragon 845 devices.
2021-10-17 22:31:45 +03:00
Gergő Móricz e1a2230e9c Add alignment wrapper to pthread_getattr_np.
This fixes stack corruption when using pthread_getattr_np on
hirsute (Ubuntu 21.04) and libc >=2.33

This should also fix #130.
2021-10-17 21:19:52 +02:00
ptitSeb 82bd4431e6 [TRAVIS] Try to use Graviton2 for Arm64 2021-10-14 08:58:27 +02:00
ptitSeb 7262288502 Merge pull request #132 from mogery/memory-map-fix
Map bricks below first 2GB of address space
2021-10-13 22:42:20 +02:00
mogery bcb0bdea77 Declare my_mmap and my_munmap to avoid warning
This adds a declaration of my_mmap and my_munmap to
src/tools/bridge.c in order to avoid a
-Wimplicit-function-declaration warning when compiling.

This should probably be moved to a header file in the
future.
2021-10-13 15:09:48 +02:00
mogery 4ca58d1f99 Fix incorrect brick cleanup
FreeBridge used free to clean up the pointer allocated by
my_mmap, which is incorrect and lead to a crash upon code
that exited gracefully.

The free was replaced with my_munmap.
2021-10-12 20:05:22 +02:00
mogery 0c27b82ff3 Map bricks below first 2GB of address space
This fixes an issue with mono where JIT compiled code would
near-call wrapped libraries, but fail because the difference
between PC and the call address did not fit into an imm32.

This was fixed by replacing posix_memalign with my_mmap and
providing the MAP_32BIT flag.

Fixes #131
2021-10-12 19:47:31 +02:00
ptitSeb 289deb3655 [DYNAREC] Added F2 0F E6 opcode 2021-10-05 23:07:32 +02:00
ptitSeb 8d69c17839 [DYNAREC] Added 67 89/C1/F7 opcodes 2021-10-05 23:06:58 +02:00
ptitSeb 348cb57240 Small fix for elfloader 2021-10-05 00:23:42 +02:00
ptitSeb 46f71f3947 Added some more crypto and ssl wrapped functions (bedrock server starts now) 2021-10-04 08:25:29 +02:00
ptitSeb 0ba4b04078 Added empty wrapped libnsl.so.1 2021-10-04 08:25:29 +02:00
ptitSeb 5a5f572162 Added Phytium profile 2021-10-02 09:46:33 +02:00
ptitSeb fb5bc122cc Added mallinfo wrapped function (for #121) 2021-09-29 08:10:06 +02:00
ptitSeb 4c328d0fca Fix g_source_new wrapped function and friends (helps Zoom) 2021-09-28 19:55:26 +02:00
ptitSeb dbce2758b2 Merge pull request #119 from Linux-Adaptation-Integrated-Toolkit/main
additional info for compilation document
2021-09-27 17:21:48 +02:00
zhaozhen 837f7edd55 additional info for compilation document 2021-09-27 22:21:49 +08:00
ptitSeb f054fb3a5f Merge pull request #118 from Jai-JAP/patch-1
Fix small typo in README.md
2021-09-26 19:12:26 +02:00
Jai A P 96831b144c Update README.md 2021-09-26 22:29:37 +05:30
ptitSeb d75116dab7 Merge pull request #117 from Linux-Adaptation-Integrated-Toolkit/main
add loongarch cmake fix and chinese document
2021-09-26 16:58:14 +02:00
zhaozhen 8da46ee305 add loongarch cmake fix and chinese document 2021-09-26 22:48:28 +08:00
ptitSeb 4cac721e74 Yeah, that too should help fix build for the untested loogarch64 support 2021-09-26 13:07:07 +02:00
ptitSeb 3fda41cbf6 Still more build fix for the untested loogarch64 support 2021-09-26 13:01:08 +02:00
ptitSeb 053d5e9b8d One more build fix for the untested loogarch64 support 2021-09-26 12:50:20 +02:00
ptitSeb 40cb14bf31 And yet another build fixe for the untested loogarch64 support 2021-09-26 12:35:45 +02:00
ptitSeb 27d18e4169 Another build fixe for the untested loogarch64 support 2021-09-26 12:24:47 +02:00
ptitSeb 5403002a36 Some build fixes for the untested loogarch64 support 2021-09-26 12:15:40 +02:00
ptitSeb 22f1a6c5ca CMake have an option for loongarch64 now 2021-09-26 12:09:16 +02:00
ptitSeb 783e9a4b74 More untested support for loongarch64 va_list 2021-09-26 12:06:01 +02:00
ptitSeb 202a067a61 Added some untested support for loongarch64 va_list 2021-09-26 11:46:04 +02:00
ptitSeb f2d1a8bc70 [DYNAREC] Somme fix for 66 83 opcodes 2021-09-26 11:29:45 +02:00
ptitSeb b6bc7922b3 Fixed some elf loading issues (like Torchlight2) 2021-09-23 19:54:52 +02:00
ptitSeb 7e4af27ba7 More work on gtk and nss3+friends 2021-09-21 20:50:52 +02:00
ptitSeb 06bbf93bf8 More work on gtk wrapping 2021-09-20 21:51:15 +02:00
ptitSeb e08bdd644b Added minimum wrapped libsecret-1 2021-09-19 21:29:06 +02:00
ptitSeb 1c5ddfafcd And 2 more wrapped gtk functions 2021-09-19 19:36:54 +02:00
ptitSeb 0f4db4c230 More gtk wrapped functions 2021-09-19 19:00:42 +02:00
ptitSeb 960ce86289 Fixed some nasty copypasta on EmuCall 2021-09-19 19:00:19 +02:00
ptitSeb b2bd3103d8 Fixed va_list conversion for aarch64 2021-09-19 18:59:34 +02:00
ptitSeb 745fd1b702 A bit more log on Interpretor mode 2021-09-19 18:59:01 +02:00
ptitSeb 6df1b65249 Added 1 more gtk function 2021-09-19 16:29:10 +02:00
ptitSeb 510f8d45e8 Added wrapped g_signal_connect_object 2021-09-19 16:24:43 +02:00
ptitSeb c5d328a5da Fixed a bug with some TLS relocation when symbol is in another elf (helps c++ softs, probably other too) 2021-09-19 16:06:24 +02:00
ptitSeb 1430c811cd Added 1 wrapped function to xcbxfixes (for #28) 2021-09-19 13:33:19 +02:00
ptitSeb ec2eadd893 More work on GTK wrapping. Still not ok, but better 2021-09-19 12:36:01 +02:00
ptitSeb 56c272c17a Added some more wrapped functions to xcb, gio2 and gobject2 (for #46) 2021-09-19 09:38:46 +02:00
ptitSeb 6f92db542b Updated wrapped libnns3, libnssutil3 and libsmime3 with more wrapped functions (from box86) 2021-09-18 21:46:00 +02:00
ptitSeb 8531750631 Added wrapped libsndfile (dwarf fortress have sound now, and seems completly playable) 2021-09-18 21:15:35 +02:00
ptitSeb 9414ece323 Added wrapped gtk2 (enough to launch Dwarf Fortress and some simple gtk2 samples) 2021-09-18 21:01:13 +02:00
ptitSeb c64cb5b92b Added 66 0F 38 39/3C opcodes ([DYNAREC] too) (for #81) 2021-09-18 08:49:55 +02:00
ptitSeb 2b1e12dafd Fixed 66 0F 3A 22 opcode for REX.W ([DYNAREC] too) (should help #81) 2021-09-16 20:54:40 +02:00
ptitSeb b4ca2be9e0 Added some libcrypto wrapped functions (for #99) 2021-09-14 21:30:41 +02:00
ptitSeb 203de52d71 Added syscall 120 (for #99) 2021-09-14 21:27:21 +02:00
ptitSeb c48333db44 Added syscall 118 (for #99) 2021-09-13 19:53:44 +02:00
ptitSeb e3552befe9 Try to use mmap first when loading elf file into memory 2021-09-12 18:37:03 +02:00
ptitSeb 6141421f92 [DYNAREC] some fixes to alternate handling and vsyscall support 2021-09-12 13:59:10 +02:00
ptitSeb 911ecc4489 Added minimal wrapped libnsp4, libnss3, libnssutil3 and linsmime3 2021-09-08 20:55:05 +02:00
ptitSeb 63ab450d87 Added 66 0F 7C ocpode (for #111) 2021-09-08 20:54:19 +02:00
ptitSeb bcc29168cd [TRAVIS] Refined the script a little bit 2021-09-08 20:53:50 +02:00
ptitSeb 4a9b0128d7 [TRAVIS] Move travis integration 2021-09-05 13:57:51 +02:00
ptitSeb 6cc56ac5f7 [TRAVIS] Specified focal as distrib to use 2021-09-05 13:42:36 +02:00
ptitSeb f53c967e18 [TRAVIS] Added python3 to travis script 2021-09-05 13:38:13 +02:00
ptitSeb b309933571 [TRAVIS] Small change 2021-09-05 13:29:17 +02:00
ptitSeb c7e8044f92 [TRAVIS] Try some travis build 2021-09-05 13:19:28 +02:00
ptitSeb 29720048e2 Started a new dev. cycle 2021-09-05 13:08:37 +02:00
191 changed files with 25848 additions and 591 deletions

No files matched your search

Executable
+24
View File
@@ -0,0 +1,24 @@
language: c
arch:
- amd64
- arm64-graviton2
os: linux
dist: focal
compiler:
- gcc
addons:
apt:
packages:
- python3
#Build steps
before_script:
- mkdir build
- cd build
- if [ "$TRAVIS_CPU_ARCH" = "arm64" ]; then cmake .. -DRK3399=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo ; else cmake .. -DLD80BITS=1 -DNOALIGN=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo ; fi
script:
- make
- ctest --output-on-failure
+49 -2
View File
@@ -2,15 +2,26 @@ cmake_minimum_required(VERSION 3.4)
cmake_policy(SET CMP0065 NEW)
SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
option(RPI4ARM64 "Set to ON if targeting an RaspberryPI4 device with multiarch arm64 and armhf" ${RPI4ARM64})
option(RK3326 "Set to ON if targeting an Rockchip RK3326 based device" ${RK3326})
option(RK3399 "Set to ON if targeting an Rockchip RK3399 based device" ${RK3399})
option(TEGRAX1 "Set to ON if targeting an Tegra X1 based device" ${TEGRAX1})
option(PHYTIUM "Set to ON if targeting an Phytium (D2000 or FT2000/4) based device" ${PHYTIUM})
option(SD845 "Set to ON if targeting a Snapragon 845 based device" ${SD845})
option(LARCH64 "Set to ON if targeting an Loongarch64 based device" ${LARCH64})
option(USE_CCACHE "Set to ON to use ccache if present in the system" ${USE_CCACHE})
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 Box64" OFF)
option(NOGIT "Set to ON if not building from a git clone repo (like when building from a zip download from github)" ${NOGIT})
if(RK3399 OR RPI4ARM64 OR RK3326 OR TEGRAX1)
if(LARCH64)
set(LD80BITS OFF CACHE BOOL "")
set(NOALIGN OFF CACHE BOOL "")
set(ARM_DYNAREC OFF CACHE BOOL "")
endif()
if(RK3399 OR RPI4ARM64 OR RK3326 OR TEGRAX1 OR PHYTIUM OR SD845)
set(LD80BITS OFF CACHE BOOL "")
set(NOALIGN OFF CACHE BOOL "")
set(ARM_DYNAREC ON CACHE BOOL "")
@@ -63,6 +74,18 @@ elseif(TEGRAX1)
add_definitions(-DTEGRAX1)
add_definitions(-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a57+crypto)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto -mcpu=cortex-a57+crypto")
elseif(PHYTIUM)
add_definitions(-DPHYSIUM)
add_definitions(-pipe -march=armv8.1-a+crc+simd+crypto)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.1-a+crc+simd+crypto+aes")
elseif(SD845)
add_definitions(-DSD845)
add_definitions(-pipe -march=armv8.2-a+simd+crypto -mtune=cortex-a75.cortex-a55)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8.2-a+simd+crypto -mtune=cortex-a75.cortex-a55")
elseif(LARCH64)
add_definitions(-DLARCH64)
add_definitions(-pipe -march=loongarch64)
set(CMAKE_ASM_FLAGS "-pipe -march=loongarch64")
elseif(ARM_DYNAREC)
set(CMAKE_ASM_FLAGS "-pipe -march=armv8-a+crc+simd+crypto")
endif()
@@ -129,6 +152,7 @@ set(ELFLOADER_SRC
"${BOX64_ROOT}/src/box64context.c"
"${BOX64_ROOT}/src/build_info.c"
"${BOX64_ROOT}/src/custommem.c"
"${BOX64_ROOT}/src/mailbox.c"
"${BOX64_ROOT}/src/dynarec/dynarec.c"
"${BOX64_ROOT}/src/elfs/elfloader.c"
"${BOX64_ROOT}/src/elfs/elfparser.c"
@@ -180,6 +204,7 @@ set(ELFLOADER_SRC
"${BOX64_ROOT}/src/tools/bridge.c"
"${BOX64_ROOT}/src/tools/callback.c"
"${BOX64_ROOT}/src/tools/my_cpuid.c"
"${BOX64_ROOT}/src/tools/gtkclass.c"
"${BOX64_ROOT}/src/tools/pathcoll.c"
"${BOX64_ROOT}/src/tools/fileutils.c"
"${BOX64_ROOT}/src/tools/wine_tools.c"
@@ -198,13 +223,23 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedcrypto.c"
"${BOX64_ROOT}/src/wrapped/wrappedcurl.c"
"${BOX64_ROOT}/src/wrapped/wrappeddbus.c"
"${BOX64_ROOT}/src/wrapped/wrappeddbusglib1.c"
"${BOX64_ROOT}/src/wrapped/wrappedexpat.c"
"${BOX64_ROOT}/src/wrapped/wrappedflac.c"
"${BOX64_ROOT}/src/wrapped/wrappedfontconfig.c"
"${BOX64_ROOT}/src/wrapped/wrappedfreetype.c"
"${BOX64_ROOT}/src/wrapped/wrappedgconf2.c"
"${BOX64_ROOT}/src/wrapped/wrappedgdkpixbuf2.c"
"${BOX64_ROOT}/src/wrapped/wrappedgdkx112.c"
"${BOX64_ROOT}/src/wrapped/wrappedgio2.c"
"${BOX64_ROOT}/src/wrapped/wrappedglib2.c"
"${BOX64_ROOT}/src/wrapped/wrappedgmodule2.c"
"${BOX64_ROOT}/src/wrapped/wrappedgnutls.c"
"${BOX64_ROOT}/src/wrapped/wrappedgobject2.c"
"${BOX64_ROOT}/src/wrapped/wrappedgssapi.c"
"${BOX64_ROOT}/src/wrapped/wrappedgssapikrb5.c"
"${BOX64_ROOT}/src/wrapped/wrappedgthread2.c"
"${BOX64_ROOT}/src/wrapped/wrappedgtkx112.c"
"${BOX64_ROOT}/src/wrapped/wrappedkrb5.c"
"${BOX64_ROOT}/src/wrapped/wrappedldlinux.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibasound.c"
@@ -222,6 +257,7 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedlibncurses.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibncurses6.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibncursesw.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibncursesw6.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibogg.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibpanel.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibpcre.c"
@@ -229,6 +265,7 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedlibresolv.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibrt.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibsm.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibsndfile.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibssl.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibtinfo.c"
"${BOX64_ROOT}/src/wrapped/wrappedlibtinfo6.c"
@@ -265,10 +302,16 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedlibz.c"
"${BOX64_ROOT}/src/wrapped/wrappedlzma.c"
"${BOX64_ROOT}/src/wrapped/wrappedmpg123.c"
"${BOX64_ROOT}/src/wrapped/wrappednsl.c"
"${BOX64_ROOT}/src/wrapped/wrappednspr4.c"
"${BOX64_ROOT}/src/wrapped/wrappednss3.c"
"${BOX64_ROOT}/src/wrapped/wrappednssutil3.c"
"${BOX64_ROOT}/src/wrapped/wrappedopenal.c"
"${BOX64_ROOT}/src/wrapped/wrappedpango.c"
"${BOX64_ROOT}/src/wrapped/wrappedpangocairo.c"
"${BOX64_ROOT}/src/wrapped/wrappedpangoft2.c"
"${BOX64_ROOT}/src/wrapped/wrappedplc4.c"
"${BOX64_ROOT}/src/wrapped/wrappedplds4.c"
"${BOX64_ROOT}/src/wrapped/wrappedpng16.c"
"${BOX64_ROOT}/src/wrapped/wrappedpulse.c"
"${BOX64_ROOT}/src/wrapped/wrappedpulsesimple.c"
@@ -278,13 +321,17 @@ set(WRAPPEDS
"${BOX64_ROOT}/src/wrapped/wrappedsdl1net.c"
"${BOX64_ROOT}/src/wrapped/wrappedsdl1sound.c"
"${BOX64_ROOT}/src/wrapped/wrappedsdl1ttf.c"
"${BOX64_ROOT}/src/wrapped/wrappedsecret1.c"
"${BOX64_ROOT}/src/wrapped/wrappedsmpeg.c"
"${BOX64_ROOT}/src/wrapped/wrappedsdl2.c"
"${BOX64_ROOT}/src/wrapped/wrappedsdl2image.c"
"${BOX64_ROOT}/src/wrapped/wrappedsdl2mixer.c"
"${BOX64_ROOT}/src/wrapped/wrappedsdl2net.c"
"${BOX64_ROOT}/src/wrapped/wrappedsdl2ttf.c"
"${BOX64_ROOT}/src/wrapped/wrappedselinux.c"
"${BOX64_ROOT}/src/wrapped/wrappedsmime3.c"
"${BOX64_ROOT}/src/wrapped/wrappedsmpeg2.c"
"${BOX64_ROOT}/src/wrapped/wrappedssl3.c"
"${BOX64_ROOT}/src/wrapped/wrappedtcmallocminimal.c"
"${BOX64_ROOT}/src/wrapped/wrappedudev0.c"
"${BOX64_ROOT}/src/wrapped/wrappedudev1.c"
@@ -415,7 +462,7 @@ add_executable(${BOX64} ${ELFLOADER_SRC} ${WRAPPEDS} "${BOX64_ROOT}/src/git_head
set_target_properties(${BOX64} PROPERTIES ENABLE_EXPORTS ON)
add_dependencies(${BOX64} WRAPPERS)
#add_dependencies(${BOX64} PRINTER)
target_link_libraries(${BOX64} m dl rt pthread)
target_link_libraries(${BOX64} c m dl rt pthread)
if(ARM_DYNAREC)
target_link_libraries(${BOX64} dynarec)
endif()
+28
View File
@@ -1,5 +1,33 @@
Current Version
======
* More functions wrapped
* Improve speed of the custom allocator used by dynarec and Hash (speedup loading)
* Added a workaround for streamwebhelper to not load it
* More opcodes added
* More wrapped libraries, including gtk2
* Added a fix for linking box64 on system using glibc 2.34+
* Some residual fixes on thread attribute handling
* Better handling of app that want 32bits jumps, like unity3d/mono (thanks mogery)
* More ARM hardware option in CMake (Phytium, NX...)
* Added loongarch64 support (interpretor only)
* Some fixes to elfloader
* Added a mecanism to cancel a Dynarec block construction if it triggers a segfault (instead of a crash)
v0.1.4
======
* Reworked README a bit
* Added some more wrapped libs
* Added some SSE4x opcodes
* Preliminary support for VSyscall (still missing VDSO)
* Added support for AES-NI cpu extension, also in Dynarec (and using ARM extension if present)
* Added some syscall
* Added some more wrapped functions
* Improvment to the handling of longjmp inside signal handlers
* Improved wrapper helpers (from rajdakin)
* Some fixes to opcodes (especially C2 flags for some x87 opcodes)
* Handling of some specific opcode as privileged instruction (instead of NOP)
* Fixed ELF signature detection
* Some fixes to a few env. var. handling
v0.1.2
======
+49
View File
@@ -47,6 +47,55 @@ If it's the first install, you also need:
sudo systemctl restart systemd-binfmt
```
#### for Snapdragon 845
Using a 64bits OS:
```
git clone https://github.com/ptitSeb/box64
cd box64
mkdir build; cd build; cmake .. -DSD845=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
make -j4
sudo make install
```
If it's the first install, you also need:
```
sudo systemctl restart systemd-binfmt
```
----
#### for Phytium
Using a 64bits OS:
```
git clone https://github.com/ptitSeb/box64
cd box64
mkdir build; cd build; cmake .. -DPHYTIUM=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
make -j4
sudo make install
```
If it's the first install, you also need:
```
sudo systemctl restart systemd-binfmt
```
#### for LoongArch
Using a 64bits OS:
```
git clone https://github.com/ptitSeb/box64
cd box64
mkdir build; cd build; cmake .. -DLARCH64=1 -DCMAKE_BUILD_TYPE=RelWithDebInfo
make -j4
sudo make install
```
If it's the first install, you also need:
```
sudo systemctl restart systemd-binfmt
```
#### for Other ARM64 Linux platforms
`mkdir build; cd build; cmake .. -DARM_DYNAREC=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo; make -j$(nproc)`
+6 -2
View File
@@ -4,6 +4,9 @@
Linux Userspace x86_64 Emulator with a twist
----
![box64 build status](https://app.travis-ci.com/ptitSeb/box64.svg?branch=main)
[中文](README_CN.md)
Box64 lets you run x86_64 Linux programs (such as games) on non-x86_64 Linux systems, like ARM (host system needs to be 64bit little-endian).
@@ -75,7 +78,7 @@ GTK libraries are not wrapped yet on box64 (contrary to box86). Many games use g
Notes about Steam
----
Not that Steam is an hybrid 32buts / 64bits. You NEED box86 to run steam, as the client app is a 32bits binaries. It also use a 64bits local server binaries, but like most stuff using libsef/chromium. it's not working correctly on box64 for now.
Not that Steam is an hybrid 32bits / 64bits. You NEED box86 to run steam, as the client app is a 32bits binaries. It also use a 64bits local server binaries, but like most stuff using libcef/chromium. it's not working correctly on box64 for now.
So: no Steam for now on box64.
----
@@ -100,8 +103,9 @@ Final word
I want to thank everyone who has contributed to box64 developpement.
There are many ways to contribute: code contribution, financial, hardware and advertisement!
So, in no particular order, I want to thank:
* For their major code contribution: rajdakin
* For their major code contribution: rajdakin, mogery
* For their major financial contribution: FlyingFathead, stormchaser3000
* For hardware contribution and LoongArch migration: [xiaoji](https://www.linuxgame.cn/), Deepin Beijing Develop Team
* For their hardware contribution: [Radxa](https://rockpi.org/), [Pine64](https://www.pine64.org/)
* For their continous advertisement of box64 project: salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/[TwisterOS](https://twisteros.com/) team, [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg), ekianjo ([Boilingsteam](https://boilingsteam.com/))
+119
View File
@@ -0,0 +1,119 @@
# box64
![Official logo](img/Box64Logo.png "Official Logo")
Linux上用户空间的x86_64应用模拟器
----
![box64 build status](https://app.travis-ci.com/ptitSeb/box64.svg?branch=main)
[English](README.md)
在ARM或其他非X86_64架构的Linux操作系统上,使用Box64可以运行x86_64 Linux程序(例如游戏),请注意,主机系统需要**64位小端**。
您可以在Youtube的[MicroLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)、[Pi Labs](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)或[The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA)频道找到更多Box64视频。
Box64使用了一些“系统”库的原生版本,例如libc、libm、SDL和OpenGL,所以它很容易与大多数应用程序集成和使用,并且在很多情况下性能会出奇的高。点击[此处](https://box86.org/index.php/2021/06/game-performances/)查看示例的基准测试分析。
Box64为ARM64平台集成了DynaRec(动态重编译器),比仅使用解释器提升5到10倍性能。关于Dynarec如何工作的更多信息,可以在[这里](https://box86.org/2021/07/inner-workings-a-high%e2%80%91level-view-of-box86-and-a-low%e2%80%91level-view-of-the-dynarec/)找到。
注:DynaRec需要针对不同平台编写一部分汇编代码,目前仅支持ARM64。
一些x64内部操作码使用“Realmode X86 Emulator Library”的部分内容,请参阅[x64primop.c](../src/emu/x64primop.c)了解版权详情
<img src="img/Box64Icon.png" width="96" height="96">
Logo和图标由grayduck制作,感谢!
----
使用方法
----
若干环境变量可以设置Box64的行为。
点击[这里](USAGE.md)了解所有的环境变量和它们的作用。
请注意:Box64的Dynarec提供了一种机制来处理JIT代码,包含内存保护和段错误信号处理程序。简单地说,如果您想用GDB来调试一个使用JIT代码的运行程序(比如mono/Unity3D),您仍然会触发很多“正常”的段错误。建议在GDB中使用类似于`handle SIGSEGV nostop`的东西,不要在每个段错误时都停止,如果您想捕获段错误,可以在`signals.c`中的`my_memprotectionhandler`中放置一个断点。
----
编译/安装
----
> 编译说明可以在[这里](COMPILE.md)查看。
----
版本历史
----
版本日志在[这里](CHANGELOG.md)。
----
32位平台的注意事项
----
Box64的工作原理是直接将函数调用从x86_64转换到主机系统,主机系统(Box64运行的系统)需要有64位的库。Box64并不包括任何64位<->32位的转换。
所以请理解,Box64只能运行64位的Linux二进制文件。对于32位的二进制文件,需要Box86(在64位的操作系统上需要所有的multiarch库或一些proot技巧)。
请注意,许多(基于mojo的)安装程序,即使存在x86_64版本,但在检测到架构为ARM64时会退回到"x86",这时会尝试使用(如果有)box86进行安装。这时你可以使用一个假的"uname",当它的参数为"-m"时返回"x86_64"。
----
关于Unity游戏模拟的注意事项
----
当前Unity游戏模拟是一件碰运气的事情。Unity使用Mono(它的信号表示,并不总能100%成功模拟)。
您还应该注意,一些Unity3D游戏需要OpenGL 3+,目前在ARM SBC(单板计算机)上提供OpenGL 3+是很棘手的。
所以,并不是所有的Unity游戏都能工作,而且可能需要很高的OpenGL配置,但现在很多游戏都能工作。
提示:如果游戏开始后在显示任何东西之前退出,在Pi4上使用`MESA_GL_VERSION_OVERRIDE=3.2`,在Panfrost上使用`PAN_MESA_DEBUG=gl3`来使用更高的配置文件。
----
关于GTK程序的注意事项
----
GTK库尚未封装在Box64内(与Box86相反)。许多游戏(包括设置)都使用gtk,例如Unity游戏的屏幕选择对话框。有些Unity游戏可以在没有该对话框的情况下运行(使用默认设置),还有一些不能。您需要将一套gtk x86_64库放在游戏目录(或其他一些Box64识别的目录)中以获得gtk支持。Box64有计划封装GTK原生库。
----
关于Steam的注意事项
----
Steam并不是32位/64位混合的,而是32位的,因此您需要Box86才能运行Steam。Steam也使用64位的本地服务器程序,但像大多数使用libcef/chromium的程序一样,在box64上暂时无法正常工作。
所以:目前在box64上无法运行Steam。
----
关于Wine的注意事项
----
box64支持64位Wine,但请注意,64位的Wine还包含32位的组件,以便能够运行32位的Windws程序。32位程序需要Box86,没有它就不能运行。在Box64和Box86共存的系统上,设置64位Wine可以同时运行32位和64位windows程序(只需分别使用 `wine` 和 `wine64`)。
----
关于Vulkan注意事项
----
Box64尚未封装原生Vulkan库,有计划这么做,但目前,vulkan程序不能在box64上运行。
----
结语
----
我要感谢所有为 box64 开发做出贡献的人。
贡献方式有很多种:代码贡献、财务帮助、捐赠捐赠和广告合作!
以下感谢不分先后:
* 代码贡献:rajdakin, mogery
* 财务帮助:FlyingFathead, stormchaser3000
* 硬件捐赠:[Radxa](https://rockpi.org/), [Pine64](https://www.pine64.org/)
* 硬件捐赠和LoongArch迁移:[xiaoji](https://www.linuxgame.cn)
* 为本项目持续的宣传:salva ([microLinux](https://www.youtube.com/channel/UCwFQAEj1lp3out4n7BeBatQ)), [PILab](https://www.youtube.com/channel/UCgfQjdc5RceRlTGfuthBs7g)/[TwisterOS](https://twisteros.com/) team, [The Byteman](https://www.youtube.com/channel/UCEr8lpIJ3B5Ctc5BvcOHSnA), [NicoD](https://www.youtube.com/channel/UCpv7NFr0-9AB5xoklh3Snhg), ekianjo ([Boilingsteam](https://boilingsteam.com/))
我还要感谢很多人,即使他们只参与了一次本项目。
(如果你的项目中使用了Box64,请不要忘记提及!)
+44
View File
@@ -0,0 +1,44 @@
# Maintainer: Jai-JAP <[email protected]>
# Author: Sebastien Chevalier <[email protected]>
pkgname=box64-arm64-git
pkgver=1116.9243ea4
pkgrel=1
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
arch=('aarch64')
url="https://github.com/ptitSeb/box64"
license=('MIT')
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
makedepends=('git' 'cmake' 'make')
provides=("${pkgname%-git}" "${pkgname%-arm64-git}-git" "${pkgname%-arm64-git}")
conflicts=("${pkgname%-git}" "${pkgname%-arm64-git}-git" "${pkgname%-arm64-git}")
source=('git+https://github.com/ptitSeb/box64')
md5sums=('SKIP')
pkgver() {
cd "$srcdir/${pkgname%-arm64-git}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd "${srcdir}/${pkgname%-arm64-git}"
if [[ ! -d ./build ]]; then
mkdir build && cd build
cmake .. -DARM_DYNAREC=ON -DCMAKE_BUILD_TYPE=Debug
fi
}
build() {
cd "$srcdir/${pkgname%-arm64-git}/build"
make -j$(nproc)
}
package() {
cd "$srcdir/${pkgname%-arm64-git}/build"
make DESTDIR="${pkgdir}/" install
# /usr/local/bin isn't in PATH by the default,
# we should move it to /usr/bin
cd ${pkgdir}
mv usr/local/bin/ usr/bin/
# cleanup when dir is empty
rmdir usr/local || exit 0
}
+44
View File
@@ -0,0 +1,44 @@
# Maintainer: Jai-JAP <[email protected]>
# Author: Sebastien Chevalier <[email protected]>
pkgname=box86-rk3399-git
pkgver=1116.9243ea4
pkgrel=1
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
arch=('aarch64')
url="https://github.com/ptitSeb/box64"
license=('MIT')
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
makedepends=('git' 'cmake' 'make')
provides=("${pkgname%-git}" "${pkgname%-rk3399-git}-git" "${pkgname%-rk3399-git}")
conflicts=("${pkgname%-git}" "${pkgname%-rk3399-git}-git" "${pkgname%-rk3399-git}")
source=('git+https://github.com/ptitSeb/box64')
md5sums=('SKIP')
pkgver() {
cd "$srcdir/${pkgname%-rk3399-git}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd "${srcdir}/${pkgname%-rk3399-git}"
if [[ ! -d ./build ]]; then
mkdir build && cd build
cmake .. -DRK3399=1 -DCMAKE_BUILD_TYPE=Debug
fi
}
build() {
cd "$srcdir/${pkgname%-rk3399-git}/build"
make -j$(nproc)
}
package() {
cd "$srcdir/${pkgname%-rk3399-git}/build"
make DESTDIR="${pkgdir}/" install
# /usr/local/bin isn't in PATH by the default,
# we should move it to /usr/bin
cd ${pkgdir}
mv usr/local/bin/ usr/bin/
# cleanup when dir is empty
rmdir usr/local || exit 0
}
+44
View File
@@ -0,0 +1,44 @@
# Maintainer: Jai-JAP <[email protected]>
# Author: Sebastien Chevalier <[email protected]>
pkgname=box64-rpi-git
pkgver=1116.9243ea4
pkgrel=1
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
arch=('aarch64')
url="https://github.com/ptitSeb/box64"
license=('MIT')
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
makedepends=('git' 'cmake' 'make')
provides=("${pkgname%-git}" "${pkgname%-rpi-git}-git" "${pkgname%-rpi-git}")
conflicts=("${pkgname%-git}" "${pkgname%-rpi-git}-git" "${pkgname%-rpi-git}")
source=('git+https://github.com/ptitSeb/box64')
md5sums=('SKIP')
pkgver() {
cd "$srcdir/${pkgname%-rpi-git}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd "${srcdir}/${pkgname%-rpi-git}"
if [[ ! -d ./build ]]; then
mkdir build && cd build
cmake .. -DRPI4ARM64=1 -DCMAKE_BUILD_TYPE=Debug
fi
}
build() {
cd "$srcdir/${pkgname%-rpi-git}/build"
make -j$(nproc)
}
package() {
cd "$srcdir/${pkgname%-rpi-git}/build"
make DESTDIR="${pkgdir}/" install
# /usr/local/bin isn't in PATH by the default,
# we should move it to /usr/bin
cd ${pkgdir}
mv usr/local/bin/ usr/bin/
# cleanup when dir is empty
rmdir usr/local || exit 0
}
+44
View File
@@ -0,0 +1,44 @@
# Maintainer: Jai-JAP <[email protected]>
# Author: Sebastien Chevalier <[email protected]>
pkgname=box64-tegra-git
pkgver=1116.9243ea4
pkgrel=1
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
arch=('aarch64')
url="https://github.com/ptitSeb/box64"
license=('MIT')
optdepends=('gl4es: OpenGL 2 for GLES 2 devices')
makedepends=('git' 'cmake' 'make')
provides=("${pkgname%-git}" "${pkgname%-tegra-git}-git" "${pkgname%-tegra-git}")
conflicts=("${pkgname%-git}" "${pkgname%-tegra-git}-git" "${pkgname%-tegra-git}")
source=('git+https://github.com/ptitSeb/box64')
md5sums=('SKIP')
pkgver() {
cd "$srcdir/${pkgname%-tegra-git}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd "${srcdir}/${pkgname%-tegra-git}"
if [[ ! -d ./build ]]; then
mkdir build && cd build
cmake .. -DTEGRAX1=1 -DCMAKE_BUILD_TYPE=Debug
fi
}
build() {
cd "$srcdir/${pkgname%-tegra-git}/build"
make -j$(nproc)
}
package() {
cd "$srcdir/${pkgname%-tegra-git}/build"
make DESTDIR="${pkgdir}/" install
# /usr/local/bin isn't in PATH by the default,
# we should move it to /usr/bin
cd ${pkgdir}
mv usr/local/bin/ usr/bin/
# cleanup when dir is empty
rmdir usr/local || exit 0
}
+43
View File
@@ -0,0 +1,43 @@
# Maintainer: Jai-JAP <[email protected]>
# Author: Sebastien Chevalier <[email protected]>
pkgname=box64-x64-git
pkgver=1116.9243ea4
pkgrel=1
pkgdesc="Linux Userspace x86_64 Emulator with a twist, targeted at ARM64 Linux devices."
arch=('aarch64')
url="https://github.com/ptitSeb/box64"
license=('MIT')
makedepends=('git' 'cmake' 'make')
provides=("${pkgname%-git}" "${pkgname%-x64-git}-git" "${pkgname%-x64-git}")
conflicts=("${pkgname%-git}" "${pkgname%-x64-git}-git" "${pkgname%-x64-git}")
source=('git+https://github.com/ptitSeb/box64')
md5sums=('SKIP')
pkgver() {
cd "$srcdir/${pkgname%-x64-git}"
printf "r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)"
}
prepare() {
cd "${srcdir}/${pkgname%-x64-git}"
if [[ ! -d ./build ]]; then
mkdir build && cd build
cmake .. -DLD80BITS=1 -DNOALIGN=1 -DCMAKE_BUILD_TYPE=Debug
fi
}
build() {
cd "$srcdir/${pkgname%-x64-git}/build"
make -j$(nproc)
}
package() {
cd "$srcdir/${pkgname%-x64-git}/build"
make DESTDIR="${pkgdir}/" install
# /usr/local/bin isn't in PATH by the default,
# we should move it to /usr/bin
cd ${pkgdir}
mv usr/local/bin/ usr/bin/
# cleanup when dir is empty
rmdir usr/local || exit 0
}
+30 -13
View File
@@ -6,6 +6,9 @@
#include <signal.h>
#include <sys/mman.h>
#ifdef DYNAREC
#include "dynarec/arm64_lock.h"
#endif
#include "box64context.h"
#include "debug.h"
#include "elfloader.h"
@@ -123,11 +126,11 @@ static void init_mutexes(box64context_t* context)
pthread_mutex_init(&context->mutex_once, &attr);
pthread_mutex_init(&context->mutex_once2, &attr);
pthread_mutex_init(&context->mutex_trace, &attr);
#ifndef DYNAREC
pthread_mutex_init(&context->mutex_lock, &attr);
#else
#ifdef DYNAREC
pthread_mutex_init(&context->mutex_dyndump, &attr);
#endif
#else
pthread_mutex_init(&context->mutex_lock, &attr);
#endif
pthread_mutex_init(&context->mutex_tls, &attr);
pthread_mutex_init(&context->mutex_thread, &attr);
pthread_mutex_init(&context->mutex_bridge, &attr);
@@ -135,10 +138,24 @@ static void init_mutexes(box64context_t* context)
pthread_mutexattr_destroy(&attr);
}
void startMailbox(void);
void haltMailbox(void);
static void atfork_prepare_box64context(void)
{
// semaphores will go in undetermined state
haltMailbox();
}
static void atfork_parent_box64context(void)
{
// reinit mailbox only
init_mutexes(my_context);
startMailbox();
}
static void atfork_child_box64context(void)
{
// (re)init mutex if it was lock before the fork
// reinit mutexes and mailbox
init_mutexes(my_context);
startMailbox();
}
EXPORTDYN
@@ -169,9 +186,9 @@ box64context_t *NewBox64Context(int argc)
context->vsyscalls[1] = AddVSyscall(context->system, 201);
context->vsyscalls[2] = AddVSyscall(context->system, 309);
// create the alternate to map at address
addAlternate((void*)context->vsyscalls[0], (void*)0xffffffffff600000);
addAlternate((void*)context->vsyscalls[1], (void*)0xffffffffff600400);
addAlternate((void*)context->vsyscalls[2], (void*)0xffffffffff600800);
addAlternate((void*)0xffffffffff600000, (void*)context->vsyscalls[0]);
addAlternate((void*)0xffffffffff600400, (void*)context->vsyscalls[1]);
addAlternate((void*)0xffffffffff600800, (void*)context->vsyscalls[2]);
// get handle to box64 itself
context->box64lib = dlopen(NULL, RTLD_NOW|RTLD_GLOBAL);
context->dlprivate = NewDLPrivate();
@@ -180,7 +197,7 @@ box64context_t *NewBox64Context(int argc)
context->argv = (char**)calloc(context->argc+1, sizeof(char*));
init_mutexes(context);
pthread_atfork(NULL, NULL, atfork_child_box64context);
pthread_atfork(atfork_prepare_box64context, atfork_parent_box64context, atfork_child_box64context);
pthread_key_create(&context->tlskey, free_tlsdatasize);
@@ -273,11 +290,11 @@ void FreeBox64Context(box64context_t** context)
pthread_mutex_destroy(&ctx->mutex_once);
pthread_mutex_destroy(&ctx->mutex_once2);
pthread_mutex_destroy(&ctx->mutex_trace);
#ifndef DYNAREC
pthread_mutex_destroy(&ctx->mutex_lock);
#else
#ifdef DYNAREC
pthread_mutex_destroy(&ctx->mutex_dyndump);
#endif
#else
pthread_mutex_destroy(&ctx->mutex_lock);
#endif
pthread_mutex_destroy(&ctx->mutex_tls);
pthread_mutex_destroy(&ctx->mutex_thread);
pthread_mutex_destroy(&ctx->mutex_bridge);
+1 -1
View File
@@ -3,6 +3,6 @@
#define BOX64_MAJOR 0
#define BOX64_MINOR 1
#define BOX64_REVISION 4
#define BOX64_REVISION 5
#endif //__BOX64_VERSION_H_
+198 -158
View File
@@ -32,8 +32,9 @@
KHASH_MAP_INIT_INT64(dynablocks, dynablock_t*)
static dynablocklist_t*** dynmap123[1<<DYNAMAP_SHIFT]; // 64bits.. in 4x16bits array
static pthread_mutex_t mutex_mmap;
static mmaplist_t *mmaplist;
static size_t mmapsize;
static mmaplist_t *mmaplist = NULL;
static size_t mmapsize = 0;
static size_t mmapcap = 0;
static kh_dynablocks_t *dblist_oversized; // store the list of oversized dynablocks (normal sized are inside mmaplist)
static uintptr_t*** box64_jmptbl3[1<<JMPTABL_SHIFT];
static uintptr_t** box64_jmptbldefault2[1<<JMPTABL_SHIFT];
@@ -43,7 +44,6 @@ static uintptr_t box64_jmptbldefault0[1<<JMPTABL_SHIFT];
#define MEMPROT_SHIFT 12
#define MEMPROT_SHIFT2 (32-MEMPROT_SHIFT)
#define MEMPROT_SIZE (1<<(32-MEMPROT_SHIFT))
static pthread_mutex_t mutex_prot;
KHASH_MAP_INIT_INT(memprot, uint8_t*)
static kh_memprot_t *memprot;
static int inited = 0;
@@ -62,8 +62,8 @@ static blocklist_t* p_blocks = NULL; // actual blocks for custom mallo
typedef union mark_s {
struct {
unsigned int fill:1;
unsigned int size:31;
unsigned int fill:1;
};
uint32_t x32;
} mark_t;
@@ -72,86 +72,123 @@ typedef struct blockmark_s {
mark_t next;
} blockmark_t;
#define NEXT_BLOCK(b) (blockmark_t*)((uintptr_t)(b) + (b)->next.size + sizeof(blockmark_t))
#define PREV_BLOCK(b) (blockmark_t*)(((uintptr_t)(b) - (b)->prev.size) - sizeof(blockmark_t))
#define LAST_BLOCK(b, s) (blockmark_t*)(((uintptr_t)(b)+(s))-sizeof(blockmark_t))
static void printBlock(blockmark_t* b, void* start)
{
printf_log(LOG_INFO, "========== Block is:\n");
do {
printf_log(LOG_INFO, "%c%p, fill=%d, size=0x%x (prev=%d/0x%x)\n", b==start?'*':' ', b, b->next.fill, b->next.size, b->prev.fill, b->prev.size);
b = NEXT_BLOCK(b);
} while(b->next.x32);
printf_log(LOG_INFO, "===================\n");
}
// get first subblock free in block. Return NULL if no block, else first subblock free (mark included), filling size
static void* getFirstBlock(void* block, size_t maxsize, size_t* size)
static void* getFirstBlock(void* block, size_t maxsize, size_t* size, void* start)
{
// get start of block
blockmark_t *m = (blockmark_t*)block;
blockmark_t *m = (blockmark_t*)((start)?start: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-sizeof(blockmark_t);
if(!m->next.fill && m->next.size>=maxsize) {
*size = m->next.size;
return m;
}
m = (blockmark_t*)((uintptr_t)m + m->next.size);
m = NEXT_BLOCK(m);
}
return NULL;
}
static size_t getMaxFreeBlock(void* block, size_t block_size)
static size_t getMaxFreeBlock(void* block, size_t block_size, void* start)
{
// get start of block
blockmark_t *m = (blockmark_t*)((uintptr_t)block+block_size-sizeof(blockmark_t)); // start 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>=sizeof(blockmark_t))?(maxsize-sizeof(blockmark_t)):0; // no block large enough left...
if(start) {
blockmark_t *m = (blockmark_t*)start;
int maxsize = 0;
while(m->next.x32) { // while there is a subblock
if(!m->next.fill && m->next.size>maxsize) {
maxsize = m->next.size;
}
m = NEXT_BLOCK(m);
}
m = (blockmark_t*)((uintptr_t)m - m->prev.size);
return (maxsize>=sizeof(blockmark_t))?maxsize:0;
} else {
blockmark_t *m = LAST_BLOCK(block, block_size); // start 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>=sizeof(blockmark_t))?maxsize:0; // no block large enough left...
}
m = PREV_BLOCK(m);
}
return (maxsize>=sizeof(blockmark_t))?maxsize:0;
}
return (maxsize>=sizeof(blockmark_t))?(maxsize-sizeof(blockmark_t)):0;
}
static void* allocBlock(void* block, void *sub, size_t size)
static void* allocBlock(void* block, void *sub, size_t size, void** pstart)
{
(void)block;
blockmark_t *s = (blockmark_t*)sub;
blockmark_t *n = (blockmark_t*)((uintptr_t)s + s->next.size);
blockmark_t *n = NEXT_BLOCK(s);
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
// check if a new mark is worth it
if(s->next.size>size+2*sizeof(blockmark_t))
s->next.size = size;
blockmark_t *m = NEXT_BLOCK(s); // 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;
m->next.size = ((uintptr_t)n - (uintptr_t)m) - sizeof(blockmark_t);
n->prev.fill = 0;
n->prev.size = m->next.size;
}
if(pstart && sub==*pstart) {
// get the next free block
m = (blockmark_t*)*pstart;
while(m->next.fill)
m = NEXT_BLOCK(m);
*pstart = (void*)m;
}
return (void*)((uintptr_t)sub + sizeof(blockmark_t));
}
static void freeBlock(void *block, void* sub)
static size_t freeBlock(void *block, void* sub, void** pstart)
{
blockmark_t *m = (blockmark_t*)block;
blockmark_t *s = (blockmark_t*)sub;
blockmark_t *n = (blockmark_t*)((uintptr_t)s + s->next.size);
blockmark_t *n = NEXT_BLOCK(s);
if(block!=sub)
m = (blockmark_t*)((uintptr_t)s - s->prev.size);
m = PREV_BLOCK(s);
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;
m->next.size += s->next.size + sizeof(blockmark_t);
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);
blockmark_t *n2 = NEXT_BLOCK(n);
//remove n
s->next.size += n->next.size;
s->next.size += n->next.size + sizeof(blockmark_t);
n2->prev.size = s->next.size;
}
if(pstart && (uintptr_t)*pstart>(uintptr_t)sub) {
*pstart = (void*)s;
}
// return free size at current block (might be bigger)
return s->next.size;
}
// return 1 if block has been expanded to new size, 0 if not
static int expandBlock(void* block, void* sub, size_t newsize)
@@ -160,15 +197,21 @@ static int expandBlock(void* block, void* sub, size_t newsize)
newsize = (newsize+3)&~3;
blockmark_t *s = (blockmark_t*)sub;
blockmark_t *n = (blockmark_t*)((uintptr_t)s + s->next.size);
blockmark_t *n = NEXT_BLOCK(s);
if(s->next.size>=newsize)
// big enough, no shrinking...
return 1;
if(s->next.fill)
return 0; // next block is filled
// unsigned bitfield of this length gets "promoted" to *signed* int...
if((size_t)(s->next.size + n->next.size) < newsize)
if((size_t)(s->next.size + n->next.size + sizeof(blockmark_t)) < newsize)
return 0; // free space too short
// ok, doing the alloc!
s->next.size = newsize+sizeof(blockmark_t);
blockmark_t *m = (blockmark_t*)((uintptr_t)s + s->next.size); // this is new n
if((s->next.size+n->next.size+sizeof(blockmark_t))-newsize<2*sizeof(blockmark_t))
s->next.size += n->next.size+sizeof(blockmark_t);
else
s->next.size = newsize+sizeof(blockmark_t);
blockmark_t *m = NEXT_BLOCK(s); // this is new n
m->prev.fill = 1;
m->prev.size = s->next.size;
if(n!=m) {
@@ -197,11 +240,11 @@ void* customMalloc(size_t size)
for(int i=0; i<n_blocks; ++i) {
if(p_blocks[i].maxfree>=size) {
size_t rsize = 0;
sub = getFirstBlock(p_blocks[i].block, size, &rsize);
sub = getFirstBlock(p_blocks[i].block, size, &rsize, NULL);
if(sub) {
void* ret = allocBlock(p_blocks[i].block, sub, size);
void* ret = allocBlock(p_blocks[i].block, sub, size, NULL);
if(rsize==p_blocks[i].maxfree)
p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size);
p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, NULL);
pthread_mutex_unlock(&mutex_blocks);
return ret;
}
@@ -225,14 +268,14 @@ void* customMalloc(size_t size)
blockmark_t* m = (blockmark_t*)p;
m->prev.x32 = 0;
m->next.fill = 0;
m->next.size = allocsize-sizeof(blockmark_t);
m = (blockmark_t*)(p+allocsize-sizeof(blockmark_t));
m->next.x32 = 0;
m->prev.fill = 0;
m->prev.size = allocsize-sizeof(blockmark_t);
m->next.size = allocsize-2*sizeof(blockmark_t);
blockmark_t* n = NEXT_BLOCK(m);
n->next.x32 = 0;
n->prev.fill = 0;
n->prev.size = m->next.size;
// alloc 1st block
void* ret = allocBlock(p_blocks[i].block, p, size);
p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size);
void* ret = allocBlock(p_blocks[i].block, p, size, NULL);
p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, NULL);
pthread_mutex_unlock(&mutex_blocks);
return ret;
}
@@ -254,7 +297,7 @@ void* customRealloc(void* p, size_t size)
&& (addr<((uintptr_t)p_blocks[i].block+p_blocks[i].size))) {
void* sub = (void*)(addr-sizeof(blockmark_t));
if(expandBlock(p_blocks[i].block, sub, size)) {
p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size);
p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size, NULL);
pthread_mutex_unlock(&mutex_blocks);
return p;
}
@@ -280,8 +323,8 @@ void customFree(void* p)
if ((addr>(uintptr_t)p_blocks[i].block)
&& (addr<((uintptr_t)p_blocks[i].block+p_blocks[i].size))) {
void* sub = (void*)(addr-sizeof(blockmark_t));
freeBlock(p_blocks[i].block, sub);
p_blocks[i].maxfree = getMaxFreeBlock(p_blocks[i].block, p_blocks[i].size);
size_t newfree = freeBlock(p_blocks[i].block, sub, NULL);
if(p_blocks[i].maxfree < newfree) p_blocks[i].maxfree = newfree;
pthread_mutex_unlock(&mutex_blocks);
return;
}
@@ -298,6 +341,8 @@ typedef struct mmaplist_s {
size_t size;
kh_dynablocks_t* dblist;
uint8_t* helper;
void* first; // first free block, to speed up things
int locked; // don't try to add stuff on locked block
} mmaplist_t;
uintptr_t FindFreeDynarecMap(dynablock_t* db, size_t size)
@@ -305,13 +350,15 @@ uintptr_t FindFreeDynarecMap(dynablock_t* db, size_t size)
// look for free space
void* sub = NULL;
for(size_t i=0; i<mmapsize; ++i) {
if(mmaplist[i].maxfree>=size) {
if(mmaplist[i].maxfree>=size+sizeof(blockmark_t) && !mmaplist[i].locked) {
mmaplist[i].locked = 1;
size_t rsize = 0;
sub = getFirstBlock(mmaplist[i].block, size, &rsize);
sub = getFirstBlock(mmaplist[i].block, size, &rsize, mmaplist[i].first);
if(sub) {
uintptr_t ret = (uintptr_t)allocBlock(mmaplist[i].block, sub, size);
if(rsize==mmaplist[i].maxfree)
mmaplist[i].maxfree = getMaxFreeBlock(mmaplist[i].block, mmaplist[i].size);
uintptr_t ret = (uintptr_t)allocBlock(mmaplist[i].block, sub, size, &mmaplist[i].first);
if(rsize==mmaplist[i].maxfree) {
mmaplist[i].maxfree = getMaxFreeBlock(mmaplist[i].block, mmaplist[i].size, mmaplist[i].first);
}
kh_dynablocks_t *blocks = mmaplist[i].dblist;
if(!blocks) {
blocks = mmaplist[i].dblist = kh_init(dynablocks);
@@ -321,9 +368,17 @@ uintptr_t FindFreeDynarecMap(dynablock_t* db, size_t size)
int r;
k = kh_put(dynablocks, blocks, (uintptr_t)ret, &r);
kh_value(blocks, k) = db;
for(size_t j=0; j<size; ++j)
mmaplist[i].helper[(uintptr_t)ret-(uintptr_t)mmaplist[i].block+j] = (j<256)?j:255;
int size255=(size<256)?size:255;
for(size_t j=0; j<size255; ++j)
mmaplist[i].helper[(uintptr_t)ret-(uintptr_t)mmaplist[i].block+j] = j;
if(size!=size255)
memset(&mmaplist[i].helper[(uintptr_t)ret-(uintptr_t)mmaplist[i].block+256], -1, size-255);
mmaplist[i].locked = 0;
return ret;
} else {
printf_log(LOG_INFO, "BOX64: Warning, sub not found, corrupted mmaplist[%zu] info?\n", i);
if(box64_log >= LOG_DEBUG)
printBlock(mmaplist[i].block, mmaplist[i].first);
}
}
}
@@ -333,8 +388,11 @@ uintptr_t FindFreeDynarecMap(dynablock_t* db, size_t size)
uintptr_t AddNewDynarecMap(dynablock_t* db, size_t size)
{
size_t i = mmapsize++;
dynarec_log(LOG_DEBUG, "Ask for DynaRec Block Alloc #%zu\n", mmapsize);
mmaplist = (mmaplist_t*)realloc(mmaplist, mmapsize*sizeof(mmaplist_t));
dynarec_log(LOG_DEBUG, "Ask for DynaRec Block Alloc #%zu/%zu\n", mmapsize, mmapcap);
if(mmapsize>mmapcap) {
mmapcap += 32;
mmaplist = (mmaplist_t*)realloc(mmaplist, mmapcap*sizeof(mmaplist_t));
}
#ifndef USE_MMAP
void *p = NULL;
if(posix_memalign(&p, box64_pagesize, MMAPSIZE)) {
@@ -353,21 +411,23 @@ uintptr_t AddNewDynarecMap(dynablock_t* db, size_t size)
#endif
setProtection((uintptr_t)p, MMAPSIZE, PROT_READ | PROT_WRITE | PROT_EXEC);
mmaplist[i].locked = 1;
mmaplist[i].block = p;
mmaplist[i].size = MMAPSIZE;
mmaplist[i].helper = (uint8_t*)calloc(1, MMAPSIZE);
mmaplist[i].first = 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);
m->next.size = MMAPSIZE-2*sizeof(blockmark_t);
blockmark_t* n = NEXT_BLOCK(m);
n->next.x32 = 0;
n->prev.fill = 0;
n->prev.size = m->next.size;
// alloc 1st block
uintptr_t sub = (uintptr_t)allocBlock(mmaplist[i].block, p, size);
mmaplist[i].maxfree = getMaxFreeBlock(mmaplist[i].block, mmaplist[i].size);
uintptr_t sub = (uintptr_t)allocBlock(mmaplist[i].block, p, size, &mmaplist[i].first);
mmaplist[i].maxfree = getMaxFreeBlock(mmaplist[i].block, mmaplist[i].size, mmaplist[i].first);
kh_dynablocks_t *blocks = mmaplist[i].dblist = kh_init(dynablocks);
kh_resize(dynablocks, blocks, 64);
khint_t k;
@@ -376,6 +436,7 @@ uintptr_t AddNewDynarecMap(dynablock_t* db, size_t size)
kh_value(blocks, k) = db;
for(size_t j=0; j<size; ++j)
mmaplist[i].helper[(uintptr_t)sub-(uintptr_t)mmaplist[i].block + j] = (j<256)?j:255;
mmaplist[i].locked = 0;
return sub;
}
@@ -388,15 +449,18 @@ void ActuallyFreeDynarecMap(dynablock_t* db, uintptr_t addr, size_t size)
if ((addr>(uintptr_t)mmaplist[i].block)
&& (addr<((uintptr_t)mmaplist[i].block+mmaplist[i].size))) {
void* sub = (void*)(addr-sizeof(blockmark_t));
freeBlock(mmaplist[i].block, sub);
mmaplist[i].maxfree = getMaxFreeBlock(mmaplist[i].block, mmaplist[i].size);
size_t newfree = freeBlock(mmaplist[i].block, sub, &mmaplist[i].first);
if(mmaplist[i].maxfree < newfree) mmaplist[i].maxfree = newfree;
kh_dynablocks_t *blocks = mmaplist[i].dblist;
if(blocks) {
khint_t k = kh_get(dynablocks, blocks, (uintptr_t)sub);
if(k!=kh_end(blocks))
kh_del(dynablocks, blocks, k);
for(size_t j=0; j<size; ++j)
mmaplist[i].helper[(uintptr_t)sub-(uintptr_t)mmaplist[i].block+j] = 0;
memset(&mmaplist[i].helper[(uintptr_t)sub-(uintptr_t)mmaplist[i].block], 0, size);
}
if(mmaplist[i].locked) {
printf_log(LOG_INFO, "BOX64: Warning, Free a chunk in a locked mmaplist[%zu]\n", i);
++mmaplist[i].locked;
}
return;
}
@@ -432,11 +496,11 @@ uintptr_t AllocDynarecMap(dynablock_t* db, size_t size)
if(!size)
return 0;
if(size>MMAPSIZE-2*sizeof(blockmark_t)) {
pthread_mutex_lock(&mutex_mmap);
//pthread_mutex_lock(&mutex_mmap);
#ifndef USE_MMAP
void *p = NULL;
if(posix_memalign(&p, box64_pagesize, size)) {
pthread_mutex_unlock(&mutex_mmap);
//pthread_mutex_unlock(&mutex_mmap);
dynarec_log(LOG_INFO, "Cannot create dynamic map of %zu bytes\n", size);
return 0;
}
@@ -444,7 +508,7 @@ uintptr_t AllocDynarecMap(dynablock_t* db, size_t size)
#else
void* p = mmap(NULL, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
if(p==(void*)-1) {
pthread_mutex_unlock(&mutex_mmap);
//pthread_mutex_unlock(&mutex_mmap);
dynarec_log(LOG_INFO, "Cannot create dynamic map of %zu bytes\n", size);
return 0;
}
@@ -459,17 +523,17 @@ uintptr_t AllocDynarecMap(dynablock_t* db, size_t size)
int ret;
k = kh_put(dynablocks, blocks, (uintptr_t)p, &ret);
kh_value(blocks, k) = db;
pthread_mutex_unlock(&mutex_mmap);
//pthread_mutex_unlock(&mutex_mmap);
return (uintptr_t)p;
}
pthread_mutex_lock(&mutex_mmap);
//pthread_mutex_lock(&mutex_mmap);
uintptr_t ret = FindFreeDynarecMap(db, size);
if(!ret)
ret = AddNewDynarecMap(db, size);
pthread_mutex_unlock(&mutex_mmap);
//pthread_mutex_unlock(&mutex_mmap);
return ret;
}
@@ -479,7 +543,7 @@ void FreeDynarecMap(dynablock_t* db, uintptr_t addr, size_t size)
if(!addr || !size)
return;
if(size>MMAPSIZE-2*sizeof(blockmark_t)) {
pthread_mutex_lock(&mutex_mmap);
//pthread_mutex_lock(&mutex_mmap);
#ifndef USE_MMAP
free((void*)addr);
#else
@@ -491,12 +555,12 @@ void FreeDynarecMap(dynablock_t* db, uintptr_t addr, size_t size)
if(k!=kh_end(blocks))
kh_del(dynablocks, blocks, k);
}
pthread_mutex_unlock(&mutex_mmap);
//pthread_mutex_unlock(&mutex_mmap);
return;
}
pthread_mutex_lock(&mutex_mmap);
//pthread_mutex_lock(&mutex_mmap);
ActuallyFreeDynarecMap(db, addr, size);
pthread_mutex_unlock(&mutex_mmap);
//pthread_mutex_unlock(&mutex_mmap);
}
dynablocklist_t* getDB(uintptr_t idx)
@@ -526,17 +590,17 @@ void addDBFromAddressRange(uintptr_t addr, size_t size)
int idx1 = (i )&((1<<DYNAMAP_SHIFT)-1);
if(!dynmap123[idx3]) {
dynablocklist_t*** p = (dynablocklist_t***)calloc(1<<DYNAMAP_SHIFT, sizeof(dynablocklist_t**));
if(arm64_lock_storeifnull(&dynmap123[idx3], p)!=p)
if(arm64_lock_storeifnull(&dynmap123[idx3], (uint64_t)p)!=(uint64_t)p)
free(p);
}
if(!dynmap123[idx3][idx2]) {
dynablocklist_t** p = (dynablocklist_t**)calloc(1<<DYNAMAP_SHIFT, sizeof(dynablocklist_t*));
if(arm64_lock_storeifnull(&dynmap123[idx3][idx2], p)!=p)
if(arm64_lock_storeifnull(&dynmap123[idx3][idx2], (uint64_t)p)!=(uint64_t)p)
free(p);
}
if(!dynmap123[idx3][idx2][idx1]) {
dynablocklist_t* p = NewDynablockList(i<<DYNAMAP_SHIFT, 1<<DYNAMAP_SHIFT, 0);
if(arm64_lock_storeifnull(&dynmap123[idx3][idx2][idx1], p)!=p)
if(arm64_lock_storeifnull(&dynmap123[idx3][idx2][idx1], (uint64_t)p)!=(uint64_t)p)
FreeDynablockList(&p);
}
}
@@ -565,13 +629,13 @@ void cleanDBFromAddressRange(uintptr_t addr, size_t size, int destroy)
if(destroy) {
if(FreeRangeDynablock(dblist, addr, size) && 0) { // dblist is empty, check if we can delete more...
// disabling this for now. It seems to cause random crash in Terraria
if(!arm64_lock_storeifref(&dynmap123[idx3][idx2][idx1], NULL, dblist)) {
if(!arm64_lock_storeifref(&dynmap123[idx3][idx2][idx1], 0, (uint64_t)dblist)) {
dynablocklist_t** p = dynmap123[idx3][idx2];
if(dynmapempty((void**)p)) {
if(!arm64_lock_storeifref(&dynmap123[idx3][idx2], NULL, p)) {
if(!arm64_lock_storeifref(&dynmap123[idx3][idx2], 0, (uint64_t)p)) {
dynablocklist_t*** p2 = dynmap123[idx3];
if(dynmapempty((void**)p2)) {
if(!arm64_lock_storeifref(&dynmap123[idx3], NULL, p2)) {
if(!arm64_lock_storeifref(&dynmap123[idx3], 0, (uint64_t)p2)) {
free(p2);
}
}
@@ -603,25 +667,25 @@ void addJumpTableIfDefault64(void* addr, void* jmp)
uintptr_t*** tbl = (uintptr_t***)malloc((1<<JMPTABL_SHIFT)*sizeof(uintptr_t**));
for(int i=0; i<(1<<JMPTABL_SHIFT); ++i)
tbl[i] = box64_jmptbldefault1;
if(arm64_lock_storeifref(&box64_jmptbl3[idx3], tbl, box64_jmptbldefault2)!=tbl)
if(arm64_lock_storeifref(&box64_jmptbl3[idx3], (uint64_t)tbl, (uint64_t)box64_jmptbldefault2)!=(uint64_t)tbl)
free(tbl);
}
if(box64_jmptbl3[idx3][idx2] == box64_jmptbldefault1) {
uintptr_t** tbl = (uintptr_t**)malloc((1<<JMPTABL_SHIFT)*sizeof(uintptr_t*));
for(int i=0; i<(1<<JMPTABL_SHIFT); ++i)
tbl[i] = box64_jmptbldefault0;
if(arm64_lock_storeifref(&box64_jmptbl3[idx3][idx2], tbl, box64_jmptbldefault1)!=tbl)
if(arm64_lock_storeifref(&box64_jmptbl3[idx3][idx2], (uint64_t)tbl, (uint64_t)box64_jmptbldefault1)!=(uint64_t)tbl)
free(tbl);
}
if(box64_jmptbl3[idx3][idx2][idx1] == box64_jmptbldefault0) {
uintptr_t* tbl = (uintptr_t*)malloc((1<<JMPTABL_SHIFT)*sizeof(uintptr_t));
for(int i=0; i<(1<<JMPTABL_SHIFT); ++i)
tbl[i] = (uintptr_t)arm64_next;
if(arm64_lock_storeifref(&box64_jmptbl3[idx3][idx2][idx1], tbl, box64_jmptbldefault0)!=tbl)
if(arm64_lock_storeifref(&box64_jmptbl3[idx3][idx2][idx1], (uint64_t)tbl, (uint64_t)box64_jmptbldefault0)!=(uint64_t)tbl)
free(tbl);
}
arm64_lock_storeifref(&box64_jmptbl3[idx3][idx2][idx1][idx0], jmp, arm64_next);
arm64_lock_storeifref(&box64_jmptbl3[idx3][idx2][idx1][idx0], (uint64_t)jmp, (uint64_t)arm64_next);
}
void setJumpTableDefault64(void* addr)
{
@@ -673,21 +737,21 @@ uintptr_t getJumpTableAddress64(uintptr_t addr)
uintptr_t*** tbl = (uintptr_t***)malloc((1<<JMPTABL_SHIFT)*sizeof(uintptr_t**));
for(int i=0; i<(1<<JMPTABL_SHIFT); ++i)
tbl[i] = box64_jmptbldefault1;
if(arm64_lock_storeifref(&box64_jmptbl3[idx3], tbl, box64_jmptbldefault2)!=tbl)
if(arm64_lock_storeifref(&box64_jmptbl3[idx3], (uint64_t)tbl, (uint64_t)box64_jmptbldefault2)!=(uint64_t)tbl)
free(tbl);
}
if(box64_jmptbl3[idx3][idx2] == box64_jmptbldefault1) {
uintptr_t** tbl = (uintptr_t**)malloc((1<<JMPTABL_SHIFT)*sizeof(uintptr_t*));
for(int i=0; i<(1<<JMPTABL_SHIFT); ++i)
tbl[i] = box64_jmptbldefault0;
if(arm64_lock_storeifref(&box64_jmptbl3[idx3][idx2], tbl, box64_jmptbldefault1)!=tbl)
if(arm64_lock_storeifref(&box64_jmptbl3[idx3][idx2], (uint64_t)tbl, (uint64_t)box64_jmptbldefault1)!=(uint64_t)tbl)
free(tbl);
}
if(box64_jmptbl3[idx3][idx2][idx1] == box64_jmptbldefault0) {
uintptr_t* tbl = (uintptr_t*)malloc((1<<JMPTABL_SHIFT)*sizeof(uintptr_t));
for(int i=0; i<(1<<JMPTABL_SHIFT); ++i)
tbl[i] = (uintptr_t)arm64_next;
if(arm64_lock_storeifref(&box64_jmptbl3[idx3][idx2][idx1], tbl, box64_jmptbldefault0)!=tbl)
if(arm64_lock_storeifref(&box64_jmptbl3[idx3][idx2][idx1], (uint64_t)tbl, (uint64_t)box64_jmptbldefault0)!=(uint64_t)tbl)
free(tbl);
}
@@ -695,9 +759,9 @@ uintptr_t getJumpTableAddress64(uintptr_t addr)
}
// Remove the Write flag from an adress range, so DB can be executed safely
void protectDBnolock(uintptr_t addr, uintptr_t size)
void internalProtectDB(uintptr_t addr, uintptr_t size)
{
dynarec_log(LOG_DEBUG, "protectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1));
dynarec_log(LOG_DEBUG, "internalProtectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1));
uintptr_t idx = (addr>>MEMPROT_SHIFT);
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
int ret;
@@ -719,32 +783,35 @@ void protectDBnolock(uintptr_t addr, uintptr_t size)
}
}
void protectDB(uintptr_t addr, size_t size)
int internalIsprotectedDB(uintptr_t addr, size_t size)
{
pthread_mutex_lock(&mutex_prot);
protectDBnolock(addr, size);
pthread_mutex_unlock(&mutex_prot);
}
void lockDB()
{
pthread_mutex_lock(&mutex_prot);
}
void unlockDB()
{
pthread_mutex_unlock(&mutex_prot);
uintptr_t idx = (addr>>MEMPROT_SHIFT);
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
int ret;
for (uintptr_t i=idx; i<=end; ++i) {
const uint32_t key = (i>>MEMPROT_SHIFT2)&0xffffffff;
khint_t k = kh_put(memprot, memprot, key, &ret);
if(ret) {
uint8_t *m = (uint8_t*)calloc(1, MEMPROT_SIZE);
kh_value(memprot, k) = m;
}
const uintptr_t ii = i&(MEMPROT_SIZE-1);
uint8_t prot = kh_value(memprot, k)[ii];
if(!(prot&PROT_DYNAREC)) {
return 0;
}
}
return 1;
}
// Add the Write flag from an adress range, and mark all block as dirty
// no log, as it can be executed inside a signal handler
void unprotectDB(uintptr_t addr, size_t size)
void internalUnprotectDB(uintptr_t addr, size_t size)
{
dynarec_log(LOG_DEBUG, "unprotectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1));
dynarec_log(LOG_DEBUG, "internalUnprotectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1));
uintptr_t idx = (addr>>MEMPROT_SHIFT);
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
int ret;
pthread_mutex_lock(&mutex_prot);
for (uintptr_t i=idx; i<=end; ++i) {
const uint32_t key = (i>>MEMPROT_SHIFT2)&0xffffffff;
khint_t k = kh_put(memprot, memprot, key, &ret);
@@ -760,20 +827,18 @@ void unprotectDB(uintptr_t addr, size_t size)
cleanDBFromAddressRange((i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, 0);
}
}
pthread_mutex_unlock(&mutex_prot);
}
#endif
void updateProtection(uintptr_t addr, size_t size, uint32_t prot)
void internalUpdateProtection(uintptr_t addr, size_t size, uint32_t prot)
{
dynarec_log(LOG_DEBUG, "updateProtection %p:%p 0x%x\n", (void*)addr, (void*)(addr+size-1), prot);
dynarec_log(LOG_DEBUG, "internalUpdateProtection %p:%p 0x%x\n", (void*)addr, (void*)(addr+size-1), prot);
uintptr_t idx = (addr>>MEMPROT_SHIFT);
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
int ret;
uintptr_t last = idx<<MEMPROT_SHIFT;
uint8_t oldprot = 0xff;
pthread_mutex_lock(&mutex_prot);
for (uintptr_t i=idx; i<=end; ++i) {
const uint32_t key = (i>>MEMPROT_SHIFT2)&0xffffffff;
khint_t k = kh_put(memprot, memprot, key, &ret);
@@ -804,16 +869,14 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot)
}
if(oldprot!=0xff)
mprotect((void*)last, (end<<MEMPROT_SHIFT)-last, oldprot&~PROT_CUSTOM); // need to optimize
pthread_mutex_unlock(&mutex_prot);
}
void setProtection(uintptr_t addr, size_t size, uint32_t prot)
void internalSetProtection(uintptr_t addr, size_t size, uint32_t prot)
{
dynarec_log(LOG_DEBUG, "setProtection %p:%p 0x%x\n", (void*)addr, (void*)(addr+size-1), prot);
dynarec_log(LOG_DEBUG, "internalSetProtection %p:%p 0x%x\n", (void*)addr, (void*)(addr+size-1), prot);
uintptr_t idx = (addr>>MEMPROT_SHIFT);
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
int ret;
pthread_mutex_lock(&mutex_prot);
for (uintptr_t i=idx; i<=end; ++i) {
const uint32_t key = (i>>MEMPROT_SHIFT2)&0xffffffff;
khint_t k = kh_put(memprot, memprot, key, &ret);
@@ -826,16 +889,14 @@ void setProtection(uintptr_t addr, size_t size, uint32_t prot)
memset(kh_value(memprot, k)+start, prot|PROT_ALLOC, finish-start+1);
i+=finish-start; // +1 from the "for" loop
}
pthread_mutex_unlock(&mutex_prot);
}
void allocProtection(uintptr_t addr, size_t size, uint32_t prot)
void internalAllocProtection(uintptr_t addr, size_t size, uint32_t prot)
{
dynarec_log(LOG_DEBUG, "allocProtection %p:%p 0x%x\n", (void*)addr, (void*)(addr+size-1), prot);
dynarec_log(LOG_DEBUG, "internalAllocProtection %p:%p 0x%x\n", (void*)addr, (void*)(addr+size-1), prot);
uintptr_t idx = (addr>>MEMPROT_SHIFT);
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
int ret;
pthread_mutex_lock(&mutex_prot);
for (uintptr_t i=idx; i<=end; ++i) {
const uint32_t key = (i>>MEMPROT_SHIFT2)&0xffffffff;
khint_t k = kh_put(memprot, memprot, key, &ret);
@@ -852,10 +913,9 @@ void allocProtection(uintptr_t addr, size_t size, uint32_t prot)
}
i+=finish-start; // +1 from the "for" loop
}
pthread_mutex_unlock(&mutex_prot);
}
void loadProtectionFromMap()
void internalLoadProtectionFromMap()
{
char buf[500];
FILE *f = fopen("/proc/self/maps", "r");
@@ -868,7 +928,7 @@ void loadProtectionFromMap()
uintptr_t s, e;
if(sscanf(buf, "%lx-%lx %c%c%c", &s, &e, &r, &w, &x)==5) {
int prot = ((r=='r')?PROT_READ:0)|((w=='w')?PROT_WRITE:0)|((x=='x')?PROT_EXEC:0);
allocProtection(s, e-s, prot);
internalAllocProtection(s, e-s, prot);
}
}
fclose(f);
@@ -882,12 +942,11 @@ static int blockempty(uint8_t* mem)
return 1;
}
void freeProtection(uintptr_t addr, size_t size)
void internalFreeProtection(uintptr_t addr, size_t size)
{
dynarec_log(LOG_DEBUG, "freeProtection %p:%p\n", (void*)addr, (void*)(addr+size-1));
dynarec_log(LOG_DEBUG, "internalFreeProtection %p:%p\n", (void*)addr, (void*)(addr+size-1));
uintptr_t idx = (addr>>MEMPROT_SHIFT);
uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT);
pthread_mutex_lock(&mutex_prot);
for (uintptr_t i=idx; i<=end; ++i) {
const uint32_t key = (i>>MEMPROT_SHIFT2)&0xffffffff;
khint_t k = kh_get(memprot, memprot, key);
@@ -903,21 +962,15 @@ void freeProtection(uintptr_t addr, size_t size)
i+=finish-start; // +1 from the "for" loop
}
}
pthread_mutex_unlock(&mutex_prot);
}
uint32_t getProtection(uintptr_t addr)
uint32_t internalGetProtection(uintptr_t addr)
{
const uint32_t key = (addr>>32)&0xffffffff;
pthread_mutex_lock(&mutex_prot);
khint_t k = kh_get(memprot, memprot, key);
if(k==kh_end(memprot)) {
pthread_mutex_unlock(&mutex_prot);
return 0;
}
if (k == kh_end(memprot)) return 0;
const uintptr_t idx = ((addr&0xffffffff)>>MEMPROT_SHIFT);
uint32_t ret = kh_val(memprot, k)[idx];
pthread_mutex_unlock(&mutex_prot);
return ret;
}
@@ -969,20 +1022,14 @@ static uintptr_t maxFree(uintptr_t addr, uintptr_t sz)
addr &= ~0xffffffffLL;
} while(1);
}
void* find32bitBlock(size_t size)
{
return findBlockNearHint(LOWEST, size);
}
void* find47bitBlock(size_t size)
void* internalFind47bitBlock(size_t size)
{
// slow iterative search... Would need something better one day
uintptr_t addr = 0x100000000LL;
pthread_mutex_lock(&mutex_prot);
do {
addr = nextFree(addr);
uintptr_t sz = maxFree(addr, size);
if(sz>=size) {
pthread_mutex_unlock(&mutex_prot);
return (void*)addr;
}
addr += sz;
@@ -993,51 +1040,47 @@ void* find47bitBlock(size_t size)
addr = nextFree(addr);
uintptr_t sz = maxFree(addr, size);
if(sz>=size) {
pthread_mutex_unlock(&mutex_prot);
return (void*)addr;
}
addr += sz;
} while(addr<0x100000000LL);
pthread_mutex_unlock(&mutex_prot);
printf_log(LOG_NONE, "Warning: cannot find a 0x%zx block in 47bits address space\n", size);
return NULL;
}
void* find47bitBlockNearHint(void* hint, size_t size)
void* internalFind47bitBlockNearHint(void* hint, size_t size)
{
// slow iterative search... Would need something better one day
uintptr_t addr = (uintptr_t)hint;
pthread_mutex_lock(&mutex_prot);
do {
addr = nextFree(addr);
uintptr_t sz = maxFree(addr, size);
if(sz>=size) {
pthread_mutex_unlock(&mutex_prot);
return (void*)addr;
}
addr += sz;
} while(addr<0x800000000000LL);
pthread_mutex_unlock(&mutex_prot);
printf_log(LOG_NONE, "Warning: cannot find a 0x%zx block in 32bits address space\n", size);
return NULL;
}
void* findBlockNearHint(void* hint, size_t size)
void* internalFindBlockNearHint(void* hint, size_t size)
{
// slow iterative search... Would need something better one day
uintptr_t addr = (uintptr_t)hint;
pthread_mutex_lock(&mutex_prot);
do {
addr = nextFree(addr);
uintptr_t sz = maxFree(addr, size);
if(sz>=size) {
pthread_mutex_unlock(&mutex_prot);
return (void*)addr;
}
addr += sz;
} while(addr<0x100000000LL);
pthread_mutex_unlock(&mutex_prot);
printf_log(LOG_NONE, "Warning: cannot find a 0x%zx block in 32bits address space\n", size);
return NULL;
}
void* internalFind32bitBlock(size_t size)
{
return internalFindBlockNearHint(LOWEST, size);
}
#undef LOWEST
int unlockCustommemMutex()
@@ -1050,7 +1093,6 @@ int unlockCustommemMutex()
ret|=(1<<B); \
}
GO(mutex_blocks, 0)
GO(mutex_prot, 1)
#ifdef DYNAREC
GO(mutex_mmap, 2)
#endif
@@ -1065,7 +1107,6 @@ void relockCustommemMutex(int locks)
pthread_mutex_lock(&A); \
GO(mutex_blocks, 0)
GO(mutex_prot, 1)
#ifdef DYNAREC
GO(mutex_mmap, 2)
#endif
@@ -1078,7 +1119,6 @@ static void init_mutexes(void)
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
pthread_mutex_init(&mutex_blocks, &attr);
pthread_mutex_init(&mutex_prot, &attr);
#ifdef DYNAREC
pthread_mutex_init(&mutex_mmap, &attr);
#endif
@@ -1146,6 +1186,7 @@ void fini_custommem_helper(box64context_t *ctx)
dblist_oversized = NULL;
}
mmapsize = 0;
mmapcap = 0;
dynarec_log(LOG_DEBUG, "Free dynamic Dynarecblocks\n");
for (uintptr_t idx3=0; idx3<=0xffff; ++idx3)
if(dynmap123[idx3]) {
@@ -1188,6 +1229,5 @@ void fini_custommem_helper(box64context_t *ctx)
free(p_blocks[i].block);
#endif
free(p_blocks);
pthread_mutex_destroy(&mutex_prot);
pthread_mutex_destroy(&mutex_blocks);
}
+2 -2
View File
@@ -88,7 +88,7 @@ arm64_lock_xchg:
ret
arm64_lock_storeifnull:
// address is x0, value is x1, x1 store to x0 only if [x0] is 0. return new [x0] value (so x1 or old value)
// address is x0, value is x1, x1 store to x0 only if [x0] is 0, return new [x0] value (so x1 or old value)
ldaxr x2, [x0]
cbnz x2, arm64_lock_storeifnull_exit
mov x2, x1
@@ -99,7 +99,7 @@ arm64_lock_storeifnull_exit:
ret
arm64_lock_storeifref:
// address is x0, value is x1, x1 store to x0 only if [x0] is x3. return new [x0] value (so x1 or old value)
// address is x0, value is x1, x1 store to x0 only if [x0] is x2, return new [x0] value (so x1 or old value)
ldaxr x3, [x0]
cmp x2, x3
bne arm64_lock_storeifref_exit
+6 -6
View File
@@ -27,13 +27,13 @@ extern void arm64_lock_read_dq(uint64_t * a, uint64_t* b, void* addr);
// STLXRD of ADDR, return 0 if ok, 1 if not
extern int arm64_lock_write_dq(uint64_t a, uint64_t b, void* addr);
// Atomicaly exchange value at [p] with val, return old p
// Atomically exchange value at [p] with val, return old p
extern uintptr_t arm64_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* arm64_lock_storeifnull(void*p, void* val);
// Atomically store val to [p] only if [p] is 0. Return new [p] value (so val or old)
extern uint64_t arm64_lock_storeifnull(void* p, uint64_t val);
// Atomicaly store value to [p] only if [p] is ref. Return new [p] value (so val or old)
extern void* arm64_lock_storeifref(void*p, void* val, void* ref);
// Atomically store val to [p] only if [p] is ref. Return new [p] value (so val or old)
extern uint64_t arm64_lock_storeifref(void* p, uint64_t val, uint64_t ref);
#endif //__ARM64_LOCK__H__
#endif //__ARM64_LOCK__H__
+3 -2
View File
@@ -18,9 +18,10 @@ arm64_next:
stp x12, x13, [sp, (8 * 4)]
stp x14, x15, [sp, (8 * 6)]
stp x16, x17, [sp, (8 * 8)]
str x18, [sp, (8 * 10)]
stp x18, x27, [sp, (8 * 10)] // also save x27(rip) to allow change in LinkNext
mov x2, lr // "from" is in lr, so put in x2
add x3, sp, 8*11 // x3 is address to change rip
// call the function
bl LinkNext
// preserve return value
@@ -31,7 +32,7 @@ arm64_next:
ldp x12, x13, [sp, (8 * 4)]
ldp x14, x15, [sp, (8 * 6)]
ldp x16, x17, [sp, (8 * 8)]
ldr x18, [sp, (8 * 10)]
ldp x18, x27, [sp, (8 * 10)]
add sp, sp, (8 * 12)
// return offset is jump address
br x3
+24 -22
View File
@@ -2,6 +2,7 @@
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include <setjmp.h>
#include "debug.h"
#include "box64context.h"
@@ -81,7 +82,9 @@ void FreeDynablock(dynablock_t* db)
// only the father free the DynarecMap
if(!db->father) {
dynarec_log(LOG_DEBUG, " -- FreeDyrecMap(%p, %d)\n", db->block, db->size);
pthread_mutex_lock(&my_context->mutex_dyndump);
FreeDynarecMap(db, (uintptr_t)db->block, db->size);
pthread_mutex_unlock(&my_context->mutex_dyndump);
}
free(db->sons);
free(db->instsize);
@@ -269,7 +272,7 @@ dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* c
if(!dynablocks->direct) {
dynablock_t** p = (dynablock_t**)calloc(dynablocks->textsz, sizeof(dynablock_t*));
if(arm64_lock_storeifnull(&dynablocks->direct, p)!=p)
if(arm64_lock_storeifnull(&dynablocks->direct, (uint64_t)p) != (uint64_t)p)
free(p); // someone already create the direct array, too late...
}
@@ -278,7 +281,7 @@ dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* c
block = (dynablock_t*)calloc(1, sizeof(dynablock_t));
block->parent = dynablocks;
dynablock_t* tmp = (dynablock_t*)arm64_lock_storeifnull(&dynablocks->direct[addr-dynablocks->text], block);
dynablock_t* tmp = (dynablock_t*)arm64_lock_storeifnull(&dynablocks->direct[addr-dynablocks->text], (uint64_t)block);
if(tmp != block) {
// a block appeard!
free(block);
@@ -290,6 +293,14 @@ dynablock_t *AddNewDynablock(dynablocklist_t* dynablocks, uintptr_t addr, int* c
return block;
}
//TODO: move this to dynrec_arm.c and track allocated structure to avoid memory leak
static __thread struct __jmp_buf_tag dynarec_jmpbuf;
void cancelFillBlock()
{
longjmp(&dynarec_jmpbuf, 1);
}
/*
return NULL if block is not found / cannot be created.
Don't create if create==0
@@ -323,29 +334,26 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
if(!created)
return block; // existing block...
#if 0
if(box64_dynarec_dump)
pthread_mutex_lock(&my_context->mutex_dyndump);
#endif
// fill the block
block->x64_addr = (void*)addr;
pthread_mutex_lock(&my_context->mutex_dyndump);
if(sigsetjmp(&dynarec_jmpbuf, 1)) {
printf_log(LOG_INFO, "FillBlock at %p triggered a segfault, cancelling\n", (void*)addr);
return NULL;
}
void* ret = FillBlock64(block, filladdr);
pthread_mutex_unlock(&my_context->mutex_dyndump);
if(!ret) {
dynarec_log(LOG_DEBUG, "Fillblock of block %p for %p returned an error\n", block, (void*)addr);
void* old = (void*)arm64_lock_storeifref(&dynablocks->direct[addr-dynablocks->text], 0, block);
if(old!=block && old) {// put it back in place, strange things are happening here!
void* old = (void*)arm64_lock_storeifref(&dynablocks->direct[addr-dynablocks->text], 0, (uint64_t)block);
if(old != block && old) {
// put it back in place, strange things are happening here!
dynarec_log(LOG_INFO, "Warning, a wild block appeared at %p: %p\n", (void*)addr, old);
// doing nothing else, the block has not be writen
// doing nothing else, the block has not been written
}
free(block);
block = NULL;
}
#if 0
if(box64_dynarec_dump)
pthread_mutex_unlock(&my_context->mutex_dyndump);
#endif
// check size
if(block && block->x64_size) {
int blocksz = block->x64_size;
@@ -358,8 +366,7 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
dblist->maxsz = blocksz;
}
}
lockDB();
protectDBnolock((uintptr_t)block->x64_addr, block->x64_size);
protectDB((uintptr_t)block->x64_addr, block->x64_size);
// fill-in jumptable
addJumpTableIfDefault64(block->x64_addr, block->block);
for(int i=0; i<block->sons_size; ++i) {
@@ -367,7 +374,6 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t
block->sons[i]->done = 1;
}
block->done = 1;
unlockDB();
}
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->x64_size:0)), (block)?block->block:0, (block)?block->size:0, (block)?block->sons_size:0);
@@ -392,13 +398,11 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, dynablock_t**
db = internalDBGetBlock(emu, addr, addr, create, *current);
} else {
father->need_test = 0;
lockDB();
protectDBnolock((uintptr_t)father->x64_addr, father->x64_size);
protectDB((uintptr_t)father->x64_addr, father->x64_size);
// fill back jumptable
addJumpTableIfDefault64(father->x64_addr, father->block);
for(int i=0; i<father->sons_size; ++i)
addJumpTableIfDefault64(father->sons[i]->x64_addr, father->sons[i]->block);
unlockDB();
}
}
return db;
@@ -420,13 +424,11 @@ dynablock_t* DBAlternateBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr)
db = internalDBGetBlock(emu, addr, filladdr, create, NULL);
} else {
father->need_test = 0;
lockDB();
protectDBnolock((uintptr_t)father->x64_addr, father->x64_size);
protectDB((uintptr_t)father->x64_addr, father->x64_size);
// fill back jumptable
addJumpTableIfDefault64(father->x64_addr, father->block);
for(int i=0; i<father->sons_size; ++i)
addJumpTableIfDefault64(father->sons[i]->x64_addr, father->sons[i]->block);
unlockDB();
}
}
return db;
+18 -5
View File
@@ -19,6 +19,7 @@
#ifdef DYNAREC
#include "dynablock.h"
#include "dynablock_private.h"
#include "bridge.h"
#endif
#ifdef DYNAREC
@@ -32,7 +33,7 @@ void arm64_epilog_fast() EXPORTDYN;
#ifdef DYNAREC
uintptr_t getX64Address(dynablock_t* db, uintptr_t arm_addr);
void* LinkNext(x64emu_t* emu, uintptr_t addr, void* x2)
void* LinkNext(x64emu_t* emu, uintptr_t addr, void* x2, uintptr_t* x3)
{
#ifdef HAVE_TRACE
if(!addr) {
@@ -45,10 +46,22 @@ void* LinkNext(x64emu_t* emu, uintptr_t addr, void* x2)
dynablock_t* block = DBGetBlock(emu, addr, 1, &current);
if(!block) {
// no block, let link table as is...
dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
printf_log(LOG_NONE, "Warning, jumping to a no-block address %p from %p (db=%p, x64addr=%p)\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL);
//tableupdate(arm64_epilog, addr, table);
return arm64_epilog;
if(hasAlternate((void*)addr)) {
printf_log(LOG_INFO, "Jmp address has alternate: %p", (void*)addr);
addr = (uintptr_t)getAlternate((void*)addr); // set new address
R_RIP = addr; // but also new RIP!
*x3 = addr; // and the RIP in x27 register
printf_log(LOG_INFO, " -> %p\n", (void*)addr);
block = DBGetBlock(emu, addr, 1, &current);
}
if(!block) {
#ifdef HAVE_TRACE
dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
printf_log(LOG_INFO, "Warning, jumping to a no-block address %p from %p (db=%p, x64addr=%p)\n", (void*)addr, x2-4, db, db?(void*)getX64Address(db, (uintptr_t)x2-4):NULL);
#endif
//tableupdate(arm64_epilog, addr, table);
return arm64_epilog;
}
}
if(!block->done) {
// not finished yet... leave linker
+16 -5
View File
@@ -338,20 +338,23 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
block->done = 1;
return (void*)block;
}
// protect the 1st page
protectDB(addr, 1);
// init the helper
dynarec_arm_t helper = {0};
helper.start = addr;
uintptr_t start = addr;
uintptr_t end = arm_pass0(&helper, addr);
if(!helper.size) {
dynarec_log(LOG_DEBUG, "Warning, null-sized dynarec block (%p)\n", (void*)addr);
if(!helper.size || !isprotectedDB(addr, 1)) {
dynarec_log(LOG_DEBUG, "Warning, null-sized dynarec block (%p) or write on purge on pass0\n", (void*)addr);
block->done = 1;
return (void*)block;
}
helper.cap = helper.size+3; // needs epilog handling
helper.insts = (instruction_arm64_t*)calloc(helper.cap, sizeof(instruction_arm64_t));
// already protect the block and compute hash signature
protectDB(addr, end-addr); //end is 1byte after actual end
if((addr&~0xfff)!=(end&~0xfff)) // need to protect some other pages too
protectDB(addr, end-addr); //end is 1byte after actual end
uint32_t hash = X31_hash_code((void*)addr, end-addr);
// pass 1, addresses, x64 jump addresses, flags
arm_pass1(&helper, addr);
@@ -422,7 +425,15 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
}
printf_log(LOG_NONE, "Table64 \t%d -> %d\n", oldtable64size*8, helper.table64size*8);
printf_log(LOG_NONE, " ------------\n");
//TODO: Cancel block and return empty one
free(helper.insts);
free(helper.next);
free(helper.table64);
free(helper.sons_x64);
free(helper.sons_arm);
FreeDynarecMap(block, (uintptr_t)p, sz);
return NULL;
}
// add table64 if needed
if(helper.table64size) {
@@ -453,7 +464,7 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) {
block->x64_size = end-start;
block->hash = X31_hash_code(block->x64_addr, block->x64_size);
// Check if something changed, to abbort if it as
if(block->hash != hash) {
if(block->hash != hash || !isprotectedDB(addr, end-addr)) {
dynarec_log(LOG_INFO, "Warning, a block changed while beeing processed hash(%p:%ld)=%x/%x\n", block->x64_addr, block->x64_size, block->hash, hash);
free(helper.sons_x64);
free(helper.sons_arm);
+10 -10
View File
@@ -172,9 +172,9 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
INST_NAME("SBB AX, Iw");
READFLAGS(X_CF);
SETFLAGS(X_ALL, SF_SET_PENDING);
i16 = F16;
i16 = F16S;
UXTHw(x1, xRAX);
MOV32w(x2, i16);
MOVZw(x2, i16);
emit_sbb16(dyn, ninst, x1, x2, x3, x4);
BFIx(xRAX, x1, 0, 16);
break;
@@ -341,7 +341,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOV32w(x5, i16);
MOVZw(x5, i16);
emit_add16(dyn, ninst, ed, x5, x2, x4);
EWBACK;
break;
@@ -350,7 +350,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOV32w(x5, i16);
MOVZw(x5, i16);
emit_or16(dyn, ninst, x1, x5, x2, x4);
EWBACK;
break;
@@ -360,7 +360,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOV32w(x5, i16);
MOVZw(x5, i16);
emit_adc16(dyn, ninst, x1, x5, x2, x4);
EWBACK;
break;
@@ -370,7 +370,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOV32w(x5, i16);
MOVZw(x5, i16);
emit_sbb16(dyn, ninst, x1, x5, x2, x4);
EWBACK;
break;
@@ -379,7 +379,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOV32w(x5, i16);
MOVZw(x5, i16);
emit_and16(dyn, ninst, x1, x5, x2, x4);
EWBACK;
break;
@@ -388,7 +388,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOV32w(x5, i16);
MOVZw(x5, i16);
emit_sub16(dyn, ninst, x1, x5, x2, x4);
EWBACK;
break;
@@ -397,7 +397,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
SETFLAGS(X_ALL, SF_SET_PENDING);
GETEW(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
MOV32w(x5, i16);
MOVZw(x5, i16);
emit_xor16(dyn, ninst, x1, x5, x2, x4);
EWBACK;
break;
@@ -407,7 +407,7 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
GETEW(x1, (opcode==0x81)?2:1);
if(opcode==0x81) i16 = F16S; else i16 = F8S;
if(i16) {
MOV32w(x2, i16);
MOVZw(x2, i16);
emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5);
} else
emit_cmp16_0(dyn, ninst, x1, x3, x4);
+21 -1
View File
@@ -381,6 +381,22 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
SXTL_32(q0, q1); // 32bits->64bits
break;
case 0x39:
INST_NAME("PMINSD Gx, Ex"); // SSE4 opcode!
nextop = F8;
GETEX(q1, 0);
GETGX(q0);
SMINQ_32(q0, q0, q1);
break;
case 0x3D:
INST_NAME("PMINSD Gx, Ex"); // SSE4 opcode!
nextop = F8;
GETEX(q1, 0);
GETGX(q0);
SMAXQ_32(q0, q0, q1);
break;
case 0xDB:
INST_NAME("AESIMC Gx, Ex"); // AES-NI
nextop = F8;
@@ -532,7 +548,11 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
GETGX(q0);
GETED(1);
u8 = F8;
VMOVQSfrom(q0, (u8&3), ed);
if(rex.w) {
VMOVQDfrom(q0, (u8&1), ed);
} else {
VMOVQSfrom(q0, (u8&3), ed);
}
break;
default:
+266 -3
View File
@@ -26,21 +26,29 @@
gd = ((nextop&0x38)>>3)+(rex.r<<3); \
a = sse_get_reg(dyn, ninst, x1, gd)
#define GETGM(a) \
gd = ((nextop&0x38)>>3); \
a = mmx_get_reg(dyn, ninst, x1, gd)
#define GETGm gd = ((nextop&0x38)>>3)
uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog)
{
(void)ip; (void)need_epilog;
uint8_t opcode = F8;
uint8_t nextop;
uint8_t gd, ed;
uint8_t gd, ed, wback, wb;
int64_t fixedaddress;
int8_t i8;
uint8_t u8;
int32_t i32;
int64_t j64;
int v0, s0;
int64_t j64, i64;
int v0, v1, s0;
MAYUSE(i32);
MAYUSE(j64);
MAYUSE(v0);
MAYUSE(v1);
MAYUSE(s0);
// REX prefix before the 67 are ignored
@@ -83,11 +91,51 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
case 0x6F:
INST_NAME("MOVQ Gm, Em");
nextop = F8;
GETGm;
if(MODREG) {
v1 = mmx_get_reg(dyn, ninst, x1, nextop&7); // no rex.b on MMX
v0 = mmx_get_reg_empty(dyn, ninst, x1, gd);
VMOVeD(v0, 0, v1, 0);
} else {
v0 = mmx_get_reg_empty(dyn, ninst, x1, gd);
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0);
VLDR64_U12(v0, ed, fixedaddress);
}
break;
case 0x7F:
INST_NAME("MOVQ Em, Gm");
nextop = F8;
GETGM(v0);
if(MODREG) {
v1 = mmx_get_reg_empty(dyn, ninst, x1, nextop&7);
VMOV(v1, v0);
} else {
addr = geted32(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, 0xfff<<3, 7, rex, 0, 0);
VSTR64_U12(v0, ed, fixedaddress);
}
break;
default:
DEFAULT;
}
break;
case 0x89:
INST_NAME("MOV Ed, Gd");
nextop=F8;
GETGD;
if(MODREG) { // reg <= reg
MOVxw_REG(xRAX+(nextop&7)+(rex.b<<3), gd);
} else { // mem <= reg
addr = geted32(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, 0);
STRxw_U12(gd, ed, fixedaddress);
}
break;
case 0x8D:
INST_NAME("LEA Gd, Ed");
nextop=F8;
@@ -103,6 +151,79 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
}
break;
case 0xC1:
nextop = F8;
switch((nextop>>3)&7) {
case 0:
INST_NAME("ROL Ed, Ib");
SETFLAGS(X_OF|X_CF, SF_SUBSET);
GETED32(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_rol32c(dyn, ninst, rex, ed, u8, x3, x4);
if(u8) { WBACK; }
break;
case 1:
INST_NAME("ROR Ed, Ib");
SETFLAGS(X_OF|X_CF, SF_SUBSET);
GETED32(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_ror32c(dyn, ninst, rex, ed, u8, x3, x4);
if(u8) { WBACK; }
break;
case 2:
INST_NAME("RCL Ed, Ib");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
GETED32W(x4, x1, 1);
u8 = F8;
MOV32w(x2, u8);
CALL_(rex.w?((void*)rcl64):((void*)rcl32), ed, x4);
WBACK;
break;
case 3:
INST_NAME("RCR Ed, Ib");
MESSAGE(LOG_DUMP, "Need Optimization\n");
READFLAGS(X_CF);
SETFLAGS(X_OF|X_CF, SF_SET);
GETED32W(x4, x1, 1);
u8 = F8;
MOV32w(x2, u8);
CALL_(rex.w?((void*)rcr64):((void*)rcr32), ed, x4);
WBACK;
break;
case 4:
case 6:
INST_NAME("SHL Ed, Ib");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
GETED32(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_shl32c(dyn, ninst, rex, ed, u8, x3, x4);
WBACK;
break;
case 5:
INST_NAME("SHR Ed, Ib");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
GETED32(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_shr32c(dyn, ninst, rex, ed, u8, x3, x4);
if(u8) {
WBACK;
}
break;
case 7:
INST_NAME("SAR Ed, Ib");
SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
GETED32(1);
u8 = (F8)&(rex.w?0x3f:0x1f);
emit_sar32c(dyn, ninst, rex, ed, u8, x3, x4);
if(u8) {
WBACK;
}
break;
}
break;
#define GO(NO, YES) \
BARRIER(2); \
JUMP(addr+i8);\
@@ -160,6 +281,148 @@ uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
case 0xE8:
return dynarec64_00(dyn, addr-1, ip, ninst, rex, rep, ok, need_epilog); // addr-1, to "put back" opcode)
case 0xF7:
nextop = F8;
switch((nextop>>3)&7) {
case 0:
case 1:
INST_NAME("TEST Ed, Id");
SETFLAGS(X_ALL, SF_SET_PENDING);
GETED32H(x1, 4);
i64 = F32S;
MOV64xw(x2, i64);
emit_test32(dyn, ninst, rex, ed, x2, x3, x4);
break;
case 2:
INST_NAME("NOT Ed");
GETED32(4);
MVNxw_REG(ed, ed);
WBACK;
break;
case 3:
INST_NAME("NEG Ed");
SETFLAGS(X_ALL, SF_SET_PENDING);
GETED32(0);
emit_neg32(dyn, ninst, rex, ed, x3, x4);
WBACK;
break;
case 4:
INST_NAME("MUL EAX, Ed");
SETFLAGS(X_ALL, SF_PENDING);
UFLAG_DF(x2, rex.w?d_mul64:d_mul32);
GETED32(0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
UMULH(gd, xRAX, ed);
MULx(xRAX, xRAX, ed);
if(gd!=xRDX) {MOVx_REG(xRDX, gd);}
} else {
UMULL(xRDX, xRAX, ed); //64 <- 32x32
MOVw_REG(xRAX, xRDX);
LSRx(xRDX, xRDX, 32);
}
UFLAG_RES(xRAX);
UFLAG_OP1(xRDX);
break;
case 5:
INST_NAME("IMUL EAX, Ed");
SETFLAGS(X_ALL, SF_PENDING);
UFLAG_DF(x2, rex.w?d_imul64:d_imul32);
GETED32(0);
if(rex.w) {
if(ed==xRDX) gd=x3; else gd=xRDX;
SMULH(gd, xRAX, ed);
MULx(xRAX, xRAX, ed);
if(gd!=xRDX) {MOVx_REG(xRDX, gd);}
} else {
SMULL(xRDX, xRAX, ed); //64 <- 32x32
MOVw_REG(xRAX, xRDX);
LSRx(xRDX, xRDX, 32);
}
UFLAG_RES(xRAX);
UFLAG_OP1(xRDX);
break;
case 6:
INST_NAME("DIV Ed");
SETFLAGS(X_ALL, SF_SET);
if(!rex.w) {
SET_DFNONE(x2);
GETED32(0);
MOVw_REG(x3, xRAX);
ORRx_REG_LSL(x3, x3, xRDX, 32);
if(MODREG) {
MOVw_REG(x4, ed);
ed = x4;
}
UDIVx(x2, x3, ed);
MSUBx(x4, x2, ed, xRAX);
MOVw_REG(xRAX, x2);
MOVw_REG(xRDX, x4);
} else {
if(ninst && dyn->insts
&& dyn->insts[ninst-1].x64.addr
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x31
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0xD2) {
SET_DFNONE(x2);
GETED32(0);
UDIVx(x2, xRAX, ed);
MSUBx(xRDX, x2, ed, xRAX);
MOVx_REG(xRAX, x2);
} else {
GETED32H(x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
CBZxw_MARK(xRDX);
if(ed!=x1) {MOVx_REG(x1, ed);}
CALL(div64, -1);
B_NEXT_nocond;
MARK;
UDIVx(x2, xRAX, ed);
MSUBx(xRDX, x2, ed, xRAX);
MOVx_REG(xRAX, x2);
SET_DFNONE(x2);
}
}
break;
case 7:
INST_NAME("IDIV Ed");
SETFLAGS(X_ALL, SF_SET);
if(!rex.w) {
SET_DFNONE(x2)
GETSED32w(0);
MOVw_REG(x3, xRAX);
ORRx_REG_LSL(x3, x3, xRDX, 32);
SDIVx(x2, x3, wb);
MSUBx(x4, x2, wb, x3);
MOVw_REG(xRAX, x2);
MOVw_REG(xRDX, x4);
} else {
if(ninst && dyn->insts
&& dyn->insts[ninst-1].x64.addr
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr)==0x48
&& *(uint8_t*)(dyn->insts[ninst-1].x64.addr+1)==0x99) {
SET_DFNONE(x2)
GETED32(0);
SDIVx(x2, xRAX, ed);
MSUBx(xRDX, x2, ed, xRAX);
MOVx_REG(xRAX, x2);
} else {
GETED32H(x1, 0); // get edd changed addr, so cannot be called 2 times for same op...
CBZxw_MARK(xRDX);
MVNx_REG(x2, xRDX);
CBZxw_MARK(x2);
if(ed!=x1) {MOVx_REG(x1, ed);}
CALL((void*)idiv64, -1);
B_NEXT_nocond;
MARK;
SDIVx(x2, xRAX, ed);
MSUBx(xRDX, x2, ed, xRAX);
MOVx_REG(xRAX, x2);
SET_DFNONE(x2)
}
}
break;
}
break;
default:
DEFAULT;
}
+3 -3
View File
@@ -209,7 +209,7 @@ void emit_shr32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int32_t c, in
if(c>1) {
LSRxw(s3, s1, c-1);
}
BFIw(xFlags, s3, 0, 1);
BFIw(xFlags, (c>1)?s3:s1, 0, 1);
}
LSRxw(s1, s1, c);
IFX(X_PEND) {
@@ -257,7 +257,7 @@ void emit_sar32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int32_t c, in
if(c>1) {
ASRxw(s3, s1, c-1);
}
BFIw(xFlags, s3, 0, 1);
BFIw(xFlags, (c>1)?s3:s1, 0, 1);
}
ASRxw(s1, s1, c);
IFX(X_PEND) {
@@ -366,7 +366,7 @@ void emit_shrd32c(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int3
if(c>1) {
LSRxw(s3, s1, c-1);
}
BFIw(xFlags, s3, 0, 1);
BFIw(xFlags, (c>1)?s3:s1, 0, 1);
}
LSRxw(s3, s1, c);
ORRxw_REG_LSL(s1, s3, s2, (rex.w?64:32)-c);
+12
View File
@@ -313,6 +313,18 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
VFMLAQS(v0, v1, q0);
break;
case 0xE6:
INST_NAME("CVTPD2DQ Gx, Ex");
nextop = F8;
GETEX(v1, 0);
GETGX_empty(v0);
u8 = sse_setround(dyn, ninst, x1, x2, x3);
FRINTXD(v0, v1);
x87_restoreround(dyn, ninst, u8);
VFCVTNSQD(v0, v0); // convert double -> int64
SQXTN_32(v0, v0); // convert int64 -> int32 with saturation in lower part, RaZ high part
break;
case 0xF0:
INST_NAME("LDDQU Gx,Ex");
nextop = F8;
+2 -1
View File
@@ -26,6 +26,7 @@
#include "dynarec_arm64_private.h"
#include "dynarec_arm64_functions.h"
#include "custommem.h"
#include "bridge.h"
void arm_fstp(x64emu_t* emu, void* p)
{
@@ -448,7 +449,7 @@ int isNativeCall(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t* calladdress, int
return 0;
if(PK(0)==0xff && PK(1)==0x25) { // "absolute" jump, maybe the GOT (well, RIP relative in fact)
uintptr_t a1 = addr + 6 + (PK32(2)); // need to add a check to see if the address is from the GOT !
addr = *(uintptr_t*)a1;
addr = (uintptr_t)getAlternate(*(void**)a1);
}
if(!addr || !getProtection(addr))
return 0;
+36 -1
View File
@@ -69,6 +69,24 @@
LDRSW_U12(x1, wback, fixedaddress); \
wb = ed = x1; \
}
#define GETED32(D) if(MODREG) { \
ed = xRAX+(nextop&7)+(rex.b<<3); \
wback = 0; \
} else { \
addr = geted32(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, D); \
LDRxw_U12(x1, wback, fixedaddress); \
ed = x1; \
}
#define GETSED32w(D) if((nextop&0xC0)==0xC0) { \
ed = xRAX+(nextop&7)+(rex.b<<3); \
SXTWx(x1, ed); \
wb = x1; \
wback = 0; \
} else { \
addr = geted32(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0xfff<<2, 3, rex, 0, D); \
LDRSW_U12(x1, wback, fixedaddress); \
wb = ed = x1; \
}
//GETEDH can use hint for ed, and r1 or r2 for wback (depending on hint). wback is 0 if ed is xEAX..xEDI
#define GETEDH(hint, D) if(MODREG) { \
ed = xRAX+(nextop&7)+(rex.b<<3); \
@@ -78,8 +96,16 @@
LDRxw_U12(hint, wback, fixedaddress); \
ed = hint; \
}
#define GETED32H(hint, D) if(MODREG) { \
ed = xRAX+(nextop&7)+(rex.b<<3); \
wback = 0; \
} else { \
addr = geted32(dyn, addr, ninst, nextop, &wback, (hint==x2)?x1:x2, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, D); \
LDRxw_U12(hint, wback, fixedaddress); \
ed = hint; \
}
//GETEDW can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI
#define GETEDW(hint, ret, D) if(MODREG) { \
#define GETEDW(hint, ret, D) if(MODREG) { \
ed = xRAX+(nextop&7)+(rex.b<<3); \
MOVxw_REG(ret, ed); \
wback = 0; \
@@ -88,6 +114,15 @@
ed = ret; \
LDRxw_U12(ed, wback, fixedaddress); \
}
#define GETED32W(hint, ret, D) if(MODREG) { \
ed = xRAX+(nextop&7)+(rex.b<<3); \
MOVxw_REG(ret, ed); \
wback = 0; \
} else { \
addr = geted32(dyn, addr, ninst, nextop, &wback, hint, &fixedaddress, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, 0, D); \
ed = ret; \
LDRxw_U12(ed, wback, fixedaddress); \
}
// Write back ed in wback (if wback not 0)
#define WBACK if(wback) {STRxw_U12(ed, wback, fixedaddress);}
// Write back ed in wback (if wback not 0)
+22 -14
View File
@@ -289,12 +289,20 @@ int LoadElfMemory(FILE* f, box64context_t* context, elfheader_t* head)
if(head->PHEntries[i].p_type == PT_LOAD) {
Elf64_Phdr * e = &head->PHEntries[i];
char* dest = (char*)e->p_paddr + head->delta;
printf_log(LOG_DEBUG, "Loading block #%zu @%p (0x%lx/0x%lx)\n", i, dest, e->p_filesz, e->p_memsz);
fseeko64(f, e->p_offset, SEEK_SET);
if(e->p_filesz) {
if(fread(dest, e->p_filesz, 1, f)!=1) {
printf_log(LOG_NONE, "Fail to read PT_LOAD part #%zu (size=%ld)\n", i, e->p_filesz);
return 1;
printf_log(LOG_DEBUG, "MMap block #%zu @%p offset=%p (0x%lx/0x%lx)\n", i, dest, (void*)e->p_offset, e->p_filesz, e->p_memsz);
void* p = (void*)-1;
if(e->p_memsz==e->p_filesz && !(e->p_align&0xfff)) {
printf_log(LOG_DEBUG, "MMap block #%zu @%p offset=%p (0x%zx/0x%zx, flags:0x%x)\n", i, dest, (void*)e->p_offset, e->p_filesz, e->p_memsz, e->p_flags);
mmap(dest, e->p_filesz, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fileno(f), e->p_offset);
}
if(p!=dest) {
printf_log(LOG_DEBUG, "Loading block #%zu %p (0x%zx/0x%zx)\n",i, dest, e->p_filesz, e->p_memsz);
fseeko64(f, e->p_offset, SEEK_SET);
if(e->p_filesz) {
if(fread(dest, e->p_filesz, 1, f)!=1) {
printf_log(LOG_NONE, "Fail to read PT_LOAD part #%zu (size=%zd)\n", i, e->p_filesz);
return 1;
}
}
}
#ifdef DYNAREC
@@ -440,12 +448,12 @@ int RelocateElfREL(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t*
case R_X86_64_GLOB_DAT:
if(head!=my_context->elfs[0] && !IsGlobalNoWeakSymbolInNative(maplib, symname, version, vername) && FindR64COPYRel(my_context->elfs[0], symname, &globoffs, &globp, version, vername)) {
// set global offs / size for the symbol
offs = sym->st_value + head->delta;
offs = sym->st_value;
end = offs + sym->st_size;
if(sym->st_size) {
printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) size=%ld on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, sym->st_size, symname);
//memmove((void*)globoffs, (void*)offs, sym->st_size); // preapply to copy part from lib to main elf
AddWeakSymbol(GetGlobalData(maplib), symname, offs, sym->st_size, version, vername);
if(sym->st_size && offs) {
printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) size=%ld on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)(offs + head->delta), (void*)globoffs, sym->st_size, symname);
memmove((void*)globoffs, (void*)offs, sym->st_size); // preapply to copy part from lib to main elf
AddWeakSymbol(GetGlobalData(maplib), symname, offs + head->delta, sym->st_size, version, vername);
} else {
printf_dump(LOG_NEVER, "Apply %s R_X86_64_GLOB_DAT with R_X86_64_COPY @%p/%p (%p/%p -> %p/%p) null sized on sym=%s \n", (bind==STB_LOCAL)?"Local":"Global", p, globp, (void*)(p?(*p):0), (void*)(globp?(*globp):0), (void*)offs, (void*)globoffs, symname);
}
@@ -570,7 +578,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
uint64_t *p = (uint64_t*)(rela[i].r_offset + head->delta);
uintptr_t offs = 0;
uintptr_t end = 0;
elfheader_t* h_tls = head;
elfheader_t* h_tls = NULL;//head;
int version = head->VerSym?((Elf64_Half*)((uintptr_t)head->VerSym+head->delta))[ELF64_R_SYM(rela[i].r_info)]:-1;
if(version!=-1) version &=0x7fff;
const char* vername = GetSymbolVersion(head, version);
@@ -740,7 +748,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
offs = getElfIndex(my_context, h_tls);
}
if(p) {
printf_dump(LOG_NEVER, "Apply %s %s @%p with sym=%s (%p -> %p)\n", "R_X86_64_DTPMOD64", (bind==STB_LOCAL)?"Local":"Global", p, symname, *(void**)p, (void*)offs);
printf_dump(LOG_NEVER, "Apply %s %s @%p with sym=%s (%p -> %p)\n", (bind==STB_LOCAL)?"Local":"Global", "R_X86_64_DTPMOD64", p, symname, *(void**)p, (void*)offs);
*p = offs;
} else {
printf_log(LOG_NONE, "Warning, Symbol %s or Elf not found, but R_X86_64_DTPMOD64 Slot Offset is NULL \n", symname);
@@ -756,7 +764,7 @@ int RelocateElfRELA(lib_t *maplib, lib_t *local_maplib, int bindnow, elfheader_t
}
// return -1;
} else {
if(h_tls)
if(!symname || symname[0]=='\0' || bind==STB_LOCAL)
offs = sym->st_value;
if(p) {
int64_t tlsoffset = offs; // it's not an offset in elf memory
+1
View File
@@ -31,6 +31,7 @@
#define GETEX_OFFS(D, O) opex=GetExO(emu, rex, nextop, D, O)
#define GETGX opgx=GetGx(emu, rex, nextop)
#define GETEM(D) opem=GetEm(emu, rex, nextop, D)
#define GETEM32(D) opem=GetEm32O(emu, rex, nextop, D, 0)
#define GETGM opgm=GetGm(emu, rex, nextop)
#define ED oped
#define GD opgd
+1
View File
@@ -1526,6 +1526,7 @@ x64emurun:
fini:
printf_log(LOG_DEBUG, "End of X86 run (%p), RIP=%p, Stack=%p, unimp=%d, emu->fork=%d, emu->uc_link=%p, emu->quit=%d\n", emu, (void*)R_RIP, (void*)R_RSP, unimp, emu->fork, emu->uc_link, emu->quit);
if(unimp) {
R_RIP = emu->old_ip;
emu->quit = 1;
+34 -1
View File
@@ -430,6 +430,24 @@ int Run660F(x64emu_t *emu, rex_t rex)
GX->sq[i] = EX->sd[i];
break;
case 0x39: /* PMINSD Gx, Ex */
nextop = F8;
GETEX(0);
GETGX;
for(int i=0; i<4; ++i)
if(GX->sd[i]>EX->sd[i])
GX->sd[i] = EX->sd[i];
break;
case 0x3A: /* PMAXSD Gx, Ex */
nextop = F8;
GETEX(0);
GETGX;
for(int i=0; i<4; ++i)
if(GX->sd[i]<EX->sd[i])
GX->sd[i] = EX->sd[i];
break;
case 0xDB: /* AESIMC Gx, Ex */
nextop = F8;
GETEX(0);
@@ -647,7 +665,10 @@ int Run660F(x64emu_t *emu, rex_t rex)
GETED(1);
GETGX;
tmp8u = F8;
GX->ud[tmp8u&0x3] = ED->dword[0];
if(rex.w)
GX->q[tmp8u&0x1] = ED->q[0];
else
GX->ud[tmp8u&0x3] = ED->dword[0];
break;
case 0x40: /* DPPS Gx, Ex, Ib */
@@ -1132,6 +1153,18 @@ int Run660F(x64emu_t *emu, rex_t rex)
GX->ud[i] = (GX->ud[i]==EX->ud[i])?0xffffffff:0;
break;
case 0x7C: /* HADDPD Gx, Ex */
nextop = F8;
GETEX(0);
GETGX;
GX->d[0] += GX->d[1];
if(EX==GX) {
GX->d[1] = GX->d[0];
} else {
GX->d[1] = EX->d[0] + EX->d[1];
}
break;
case 0x7E: /* MOVD Ed, Gx */
nextop = F8;
GETED(0);
+14
View File
@@ -65,6 +65,20 @@ int Run670F(x64emu_t *emu, rex_t rex, int rep)
CLEAR_FLAG(F_OF); CLEAR_FLAG(F_AF); CLEAR_FLAG(F_SF);
break;
case 0x6F: /* MOVQ Gm, Em */
nextop = F8;
GETEM32(0);
GETGM;
GM->q = EM->q;
break;
case 0x7F: /* MOVQ Em, Gm */
nextop = F8;
GETEM32(0);
GETGM;
EM->q = GM->q;
break;
default:
return 1;
}
+16 -1
View File
@@ -32,14 +32,21 @@ int32_t EXPORT my___libc_start_main(x64emu_t* emu, int *(main) (int, char * *, c
{
(void)argc; (void)ubp_av; (void)fini; (void)rtld_fini; (void)stack_end;
// let's cheat and set all args...
if(init) {
Push64(emu, GetRBP(emu)); // set frame pointer
SetRBP(emu, GetRSP(emu)); // save RSP
SetRSP(emu, GetRSP(emu)&~0xFLL); // Align RSP
PushExit(emu);
SetRDX(emu, (uint64_t)my_context->envv);
SetRSI(emu, (uint64_t)my_context->argv);
SetRDI(emu, (uint64_t)my_context->argc);
R_RIP=(uint64_t)*init;
printf_log(LOG_DEBUG, "Calling init(%p) from __libc_start_main\n", *init);
DynaRun(emu);
if(emu->error) // any error, don't bother with more
return 0;
SetRSP(emu, GetRBP(emu)); // restore RSP
SetRBP(emu, Pop64(emu)); // restore RBP
emu->quit = 0;
}
printf_log(LOG_DEBUG, "Transfert to main(%d, %p, %p)=>%p from __libc_start_main\n", my_context->argc, my_context->argv, my_context->envv, main);
@@ -1276,6 +1283,14 @@ sse_regs_t* GetEx32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr
} else return (sse_regs_t*)GetECommon32O(emu, rex, m, delta, offset);
}
mmx87_regs_t* GetEm32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset)
{
uint8_t m = v&0xC7; // filter Ed
if(m>=0xC0) {
return &emu->mmx[(m&0x07)];
} else return (mmx87_regs_t*)GetECommon32O(emu, rex, m, delta, offset);
}
reg64_t* GetGd(x64emu_t *emu, rex_t rex, uint8_t v)
{
+1
View File
@@ -94,6 +94,7 @@ reg64_t* GetGd(x64emu_t *emu, rex_t rex, uint8_t v);
#define GetGw GetGd
reg64_t* GetGb(x64emu_t *emu, rex_t rex, uint8_t v);
mmx87_regs_t* GetGm(x64emu_t *emu, rex_t rex, uint8_t v);
mmx87_regs_t* GetEm32O(x64emu_t *emu, rex_t rex, uint8_t v, uint8_t delta, uintptr_t offset);
sse_regs_t* GetGx(x64emu_t *emu, rex_t rex, uint8_t v);
void UpdateFlags(x64emu_t *emu);
+2
View File
@@ -132,6 +132,8 @@ scwrap_t syscallwrap[] = {
{ 96, __NR_gettimeofday, 2},
{ 97, __NR_getrlimit, 2},
{ 101, __NR_ptrace, 4},
{ 118, __NR_getresuid, 3},
{ 120, __NR_getresgid, 3},
{ 125, __NR_capget, 2},
{ 126, __NR_capset, 2},
{ 127, __NR_rt_sigpending, 2},
+3
View File
@@ -153,6 +153,9 @@ int my_arch_prctl(x64emu_t *emu, int code, void* addr)
my_context->segtls[3].present = 1;
pthread_setspecific(my_context->segtls[3].key, (void*)my_context->segtls[3].base);
return 0;
case ARCH_GET_FS:
*(void**)addr = GetSegmentBase(emu->segs[_FS]);
return 0;
}
// other are unsupported
printf_log(LOG_INFO, "warning, call to unsupported arch_prctl(0x%x, %p)\n", code, addr);
+2 -3
View File
@@ -38,6 +38,7 @@ uintptr_t getJumpTableAddress64(uintptr_t addr);
#define PROT_ALLOC 0x40
#define PROT_CUSTOM (PROT_DYNAREC|PROT_ALLOC)
// Implemented in mailbox.c
void updateProtection(uintptr_t addr, size_t size, uint32_t prot);
void setProtection(uintptr_t addr, size_t size, uint32_t prot);
void freeProtection(uintptr_t addr, size_t size);
@@ -45,10 +46,8 @@ uint32_t getProtection(uintptr_t addr);
void loadProtectionFromMap();
#ifdef DYNAREC
void protectDB(uintptr_t addr, size_t size);
void protectDBnolock(uintptr_t addr, size_t size);
void unprotectDB(uintptr_t addr, size_t size);
void lockDB();
void unlockDB();
int isprotectedDB(uintptr_t addr, size_t size);
#endif
void* find32bitBlock(size_t size);
void* findBlockNearHint(void* hint, size_t size);
+6 -3
View File
@@ -1,6 +1,8 @@
#ifndef __DEBUG_H_
#define __DEBUG_H_
#ifndef __DEBUG_H__
#define __DEBUG_H__
#include <stdint.h>
#include <stdio.h>
typedef struct box64context_s box64context_t;
extern int box64_log; // log level
@@ -18,6 +20,7 @@ extern int arm64_asimd;
extern int arm64_aes;
extern int arm64_pmull;
extern int arm64_crc32;
extern int arm64_atomics;
#endif
#endif
extern int dlsym_error; // log dlsym error
@@ -60,4 +63,4 @@ extern FILE* ftrace;
#define EXPORTDYN
#endif
#endif //__DEBUG_H_
#endif //__DEBUG_H__
+3
View File
@@ -29,4 +29,7 @@ dynablock_t* DBAlternateBlock(x64emu_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* created);
// for use in signal handler
void cancelFillBlock();
#endif //__DYNABLOCK_H_
+3 -3
View File
@@ -2,11 +2,11 @@
#define _GLOBAL_SYMBOLS_H_
//GTK stuff
//void my_checkGlobalGdkDisplay();
//void my_setGlobalGThreadsInit();
void my_checkGlobalGdkDisplay();
void my_setGlobalGThreadsInit();
//void** my_GetGTKDisplay();
//void** my_GetGthreadsGotInitialized(); // defined in wrappedgthread2
void** my_GetGthreadsGotInitialized(); // defined in wrappedgthread2
// NCurse / TInfo
void my_checkGlobalTInfo();
+338
View File
@@ -0,0 +1,338 @@
#ifndef __GTKCLASS_H__
#define __GTKCLASS_H__
#include <stdint.h>
#include <stddef.h>
#include "globalsymbols.h"
typedef struct box64context_s box64context_t;
typedef struct bridge_s bridge_t;
typedef struct my_GValue_s
{
size_t 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;
typedef struct my_GObjectClass_s
{
size_t g_type_class;
void* construct_properties;
void* (*constructor) (int type, uint32_t n_construct_properties, void* construct_properties);
void (*set_property) (void* object, uint32_t property_id, void* value, void* pspec);
void (*get_property) (void* object, uint32_t property_id, void* value, void* pspec);
void (*dispose) (void* object);
void (*finalize) (void* object);
void (*dispatch_properties_changed) (void* object, uint32_t n_pspecs, void* pspecs);
void (*notify) (void* object, void* pspec);
void (*constructed) (void* object);
uint32_t flags;
void* pdummy[6];
} my_GObjectClass_t;
typedef struct my_GtkObjectClass_s
{
my_GObjectClass_t parent_class;
void (*set_arg) (void* object, void* arg, uint32_t arg_id);
void (*get_arg) (void* object, void* arg, uint32_t arg_id);
void (*destroy) (void* object);
} my_GtkObjectClass_t;
typedef struct my_GtkWidgetClass_s
{
my_GtkObjectClass_t parent_class;
uint32_t activate_signal;
uint32_t set_scroll_adjustments_signal;
void (*dispatch_child_properties_changed) (void* widget, uint32_t n_pspecs, void* pspecs);
void (* show) (void* widget);
void (* show_all) (void* widget);
void (* hide) (void* widget);
void (* hide_all) (void* widget);
void (* map) (void* widget);
void (* unmap) (void* widget);
void (* realize) (void* widget);
void (* unrealize) (void* widget);
void (* size_request) (void* widget, void* requisition);
void (* size_allocate) (void* widget, void* allocation);
void (* state_changed) (void* widget, int previous_state);
void (* parent_set) (void* widget, void* previous_parent);
void (* hierarchy_changed) (void* widget, void* previous_toplevel);
void (* style_set) (void* widget, void* previous_style);
void (* direction_changed) (void* widget, int previous_direction);
void (* grab_notify) (void* widget, int was_grabbed);
void (* child_notify) (void* widget, void* pspec);
int (* mnemonic_activate) (void* widget, int group_cycling);
void (* grab_focus) (void* widget);
int (* focus) (void* widget, int direction);
int (* event) (void* widget, void* event);
int (* button_press_event) (void* widget, void* event);
int (* button_release_event) (void* widget, void* event);
int (* scroll_event) (void* widget, void* event);
int (* motion_notify_event) (void* widget, void* event);
int (* delete_event) (void* widget, void* event);
int (* destroy_event) (void* widget, void* event);
int (* expose_event) (void* widget, void* event);
int (* key_press_event) (void* widget, void* event);
int (* key_release_event) (void* widget, void* event);
int (* enter_notify_event) (void* widget, void* event);
int (* leave_notify_event) (void* widget, void* event);
int (* configure_event) (void* widget, void* event);
int (* focus_in_event) (void* widget, void* event);
int (* focus_out_event) (void* widget, void* event);
int (* map_event) (void* widget, void* event);
int (* unmap_event) (void* widget, void* event);
int (* property_notify_event) (void* widget, void* event);
int (* selection_clear_event) (void* widget, void* event);
int (* selection_request_event) (void* widget, void* event);
int (* selection_notify_event) (void* widget, void* event);
int (* proximity_in_event) (void* widget, void* event);
int (* proximity_out_event) (void* widget, void* event);
int (* visibility_notify_event) (void* widget, void* event);
int (* client_event) (void* widget, void* event);
int (* no_expose_event) (void* widget, void* event);
int (* window_state_event) (void* widget, void* event);
void (* selection_get) (void* widget, void* selection_data, uint32_t info, uint32_t time_);
void (* selection_received) (void* widget, void* selection_data, uint32_t time_);
void (* drag_begin) (void* widget, void* context);
void (* drag_end) (void* widget, void* context);
void (* drag_data_get) (void* widget, void* context, void* selection_data, uint32_t info, uint32_t time_);
void (* drag_data_delete) (void* widget, void* context);
void (* drag_leave) (void* widget, void* context,uint32_t time_);
int (* drag_motion) (void* widget, void* context, int32_t x, int32_t y, uint32_t time_);
int (* drag_drop) (void* widget, void* context, int32_t x, int32_t y, uint32_t time_);
void (* drag_data_received) (void* widget, void* context, int32_t x, int32_t y, void* selection_data, uint32_t info, uint32_t time_);
int (* popup_menu) (void* widget);
int (* show_help) (void* widget, int help_type);
void*(*get_accessible) (void* widget);
void (*screen_changed) (void* widget, void* previous_screen);
int (*can_activate_accel) (void* widget, uint32_t signal_id);
int (*grab_broken_event) (void* widget, void* event);
void (* composited_changed) (void* widget);
int (* query_tooltip) (void* widget, int32_t x, int32_t y, int keyboard_tooltip, void* tooltip);
void (*_gtk_reserved5) (void);
void (*_gtk_reserved6) (void);
void (*_gtk_reserved7) (void);
} my_GtkWidgetClass_t;
typedef struct my_GtkContainerClass_s
{
my_GtkWidgetClass_t parent_class;
void (*add) (void* container, void* widget);
void (*remove) (void* container, void* widget);
void (*check_resize) (void* container);
void (*forall) (void* container, int include_internals, void* callback, void* callback_data);
void (*set_focus_child) (void* container, void* widget);
int (*child_type) (void* container);
void* (*composite_name) (void* container, void* child);
void (*set_child_property) (void* container, void* child, uint32_t property_id, void* value, void* pspec);
void (*get_child_property) (void* container, void* child, uint32_t property_id, void* value, void* pspec);
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
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;
typedef struct my_GtkBinClass_s
{
my_GtkContainerClass_t parent_class;
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
} my_GtkBinClass_t;
typedef struct my_GtkWindowClass_s {
my_GtkBinClass_t parent_class;
void (* set_focus) (void* window, void* focus);
int (* frame_event) (void* window, void* event);
void (* activate_focus) (void* window);
void (* activate_default) (void* window);
void (* move_focus) (void* window, int direction);
void (*keys_changed) (void* window);
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
} my_GtkWindowClass_t;
typedef struct my_MetaFramesClass_s
{
my_GtkWindowClass_t parent_class;
} my_MetaFramesClass_t;
typedef struct my_GtkTableClass_s
{
my_GtkContainerClass_t parent_class;
} my_GtkTableClass_t;
typedef struct my_GtkFixedClass_s
{
my_GtkContainerClass_t parent_class;
} my_GtkFixedClass_t;
// GTypeValueTable
typedef struct my_GTypeValueTable_s {
void (*value_init) (void* value);
void (*value_free) (void* value);
void (*value_copy) (void* src_value, void* dest_value);
void* (*value_peek_pointer) (void* value);
void* collect_format;
void* (*collect_value) (void* value, uint32_t n_collect_values, void* collect_values, uint32_t collect_flags);
void* lcopy_format;
void* (*lcopy_value) (void* value, uint32_t n_collect_values, void* collect_values, uint32_t collect_flags);
} my_GTypeValueTable_t;
// GTypeInfo
typedef void (*GBaseInitFunc) (void* g_class);
typedef void (*GBaseFinalizeFunc) (void* g_class);
typedef void (*GClassInitFunc) (void* g_class, void* class_data);
typedef void (*GClassFinalizeFunc) (void* g_class, void* class_data);
typedef void (*GInstanceInitFunc) (void* instance, void* g_class);
typedef struct my_GTypeInfo_s {
uint16_t class_size;
GBaseInitFunc base_init;
GBaseFinalizeFunc base_finalize;
GClassInitFunc class_init;
GClassFinalizeFunc class_finalize;
void* class_data;
uint16_t instance_size;
uint16_t n_preallocs;
GInstanceInitFunc instance_init;
my_GTypeValueTable_t* value_table;
} my_GTypeInfo_t;
// GtkTypeInfo
typedef GBaseInitFunc GtkClassInitFunc;
typedef GInstanceInitFunc GtkObjectInitFunc;
typedef struct my_GtkTypeInfo_s {
void* type_name;
uint32_t object_size;
uint32_t class_size;
GtkClassInitFunc class_init_func;
GtkObjectInitFunc object_init_func;
void* reserved_1;
void* reserved_2;
GtkClassInitFunc base_class_init_func;
} my_GtkTypeInfo_t ;
my_GTypeValueTable_t* findFreeGTypeValueTable(my_GTypeValueTable_t* fcts);
my_GTypeInfo_t* findFreeGTypeInfo(my_GTypeInfo_t* fcts, size_t parent);
my_GtkTypeInfo_t* findFreeGtkTypeInfo(my_GtkTypeInfo_t* fcts, size_t parent);
void InitGTKClass(bridge_t *bridge);
void FiniGTKClass();
#define GTKCLASSES() \
GTKCLASS(GObject) \
GTKCLASS(GtkObject) \
GTKCLASS(GtkWidget) \
GTKCLASS(GtkContainer) \
GTKCLASS(GtkAction) \
GTKCLASS(GtkLabel) \
GTKCLASS(GtkMisc) \
GTKCLASS(GtkTreeView) \
GTKCLASS(GtkBin) \
GTKCLASS(GtkWindow) \
GTKCLASS(GtkTable) \
GTKCLASS(GtkFixed) \
GTKCLASS(MetaFrames) \
#define GTKCLASS(A) void Set##A##ID(size_t id);
GTKCLASSES()
#undef GTKCLASS
void SetGTypeName(void* f);
void AutoBridgeGtk(void*(*ref)(size_t), void(*unref)(void*));
void* wrapCopyGTKClass(void* cl, size_t type);
void* unwrapCopyGTKClass(void* klass, size_t type);
typedef struct my_signal_s {
uint64_t sign; // signature
void* data;
uintptr_t c_handler;
uintptr_t destroy;
} my_signal_t;
// some random sign to identify a my_signal_t
#define SIGN 0xFB3405EB4510AA00LL
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);
void my_add_signal_offset(size_t klass, uint32_t offset, int n);
#endif //__GTKCLASS_H__
+73 -41
View File
@@ -21,31 +21,31 @@ typedef struct {
void *reg_save_area;
} va_list[1];
*/
#define CREATE_SYSV_VALIST(A) \
va_list sysv_varargs; \
#define CREATE_SYSV_VALIST(A) \
va_list sysv_varargs; \
sysv_varargs->gp_offset=X64_VA_MAX_REG; \
sysv_varargs->fp_offset=X64_VA_MAX_XMM; \
sysv_varargs->reg_save_area=A; \
sysv_varargs->overflow_arg_area=A;
sysv_varargs->reg_save_area=(A); \
sysv_varargs->overflow_arg_area=A
#define CONVERT_VALIST(A) \
va_list sysv_varargs; \
sysv_varargs->gp_offset=A->gp_offset; \
sysv_varargs->fp_offset=A->fp_offset; \
sysv_varargs->reg_save_area=A->reg_save_area; \
sysv_varargs->overflow_arg_area=A->overflow_arg_area;
#define CONVERT_VALIST(A) \
va_list sysv_varargs; \
sysv_varargs->gp_offset=(A)->gp_offset; \
sysv_varargs->fp_offset=(A)->fp_offset; \
sysv_varargs->reg_save_area=(A)->reg_save_area; \
sysv_varargs->overflow_arg_area=(A)->overflow_arg_area;
#define CREATE_VALIST_FROM_VAARG(STACK, SCRATCH, N) \
va_list sysv_varargs; \
sysv_varargs->gp_offset=(6-((N<6)?N:6))*8;\
sysv_varargs->fp_offset=(6*8); \
sysv_varargs->reg_save_area=SCRATCH; \
sysv_varargs->overflow_arg_area=STACK; \
{ \
uint64_t *p = (uint64_t*)SCRATCH; \
p[0]=R_RDI; p[1]=R_RSI; p[2]=R_RDX; \
p[3]=R_RCX; p[4]=R_R8; p[5]=R_R9; \
memcpy(&p[6], emu->xmm, 8*16); \
va_list sysv_varargs; \
sysv_varargs->gp_offset=(6-(((N)<6)?(N):6))*8; \
sysv_varargs->fp_offset=(6*8); \
sysv_varargs->reg_save_area=(SCRATCH); \
sysv_varargs->overflow_arg_area=(STACK); \
{ \
uint64_t *p = (uint64_t*)(SCRATCH); \
p[0]=R_RDI; p[1]=R_RSI; p[2]=R_RDX; \
p[3]=R_RCX; p[4]=R_R8; p[5]=R_R9; \
memcpy(&p[6], emu->xmm, 8*16); \
}
@@ -66,28 +66,28 @@ typedef struct va_list {
va_list sysv_varargs; \
sysv_varargs.__gr_offs=(8*8); \
sysv_varargs.__vr_offs=(8*16); \
sysv_varargs.__stack=A;
sysv_varargs.__stack=(A)
#define CONVERT_VALIST(A) \
va_list sysv_varargs; \
sysv_varargs.__gr_offs=-(6*8)+A->gp_offset; \
sysv_varargs.__vr_offs=-(8*16)+(A->fp_offset-X64_VA_MAX_REG); \
sysv_varargs.__stack=A->overflow_arg_area; \
sysv_varargs.__gr_top=A->reg_save_area + X64_VA_MAX_REG; \
sysv_varargs.__vr_top=A->reg_save_area + X64_VA_MAX_XMM;
#define CONVERT_VALIST(A) \
va_list sysv_varargs; \
sysv_varargs.__gr_offs=-(6*8)+(A)->gp_offset; \
sysv_varargs.__vr_offs=-(8*16)+((A)->fp_offset-X64_VA_MAX_REG); \
sysv_varargs.__stack=(A)->overflow_arg_area; \
sysv_varargs.__gr_top=(A)->reg_save_area + X64_VA_MAX_REG; \
sysv_varargs.__vr_top=(A)->reg_save_area + X64_VA_MAX_XMM;
#define CREATE_VALIST_FROM_VAARG(STACK, SCRATCH, N) \
va_list sysv_varargs; \
sysv_varargs.__gr_offs=(8*(2+((N<6)?N:6))); \
sysv_varargs.__vr_offs=0; \
sysv_varargs.__stack=STACK; \
sysv_varargs.__gr_top=SCRATCH + X64_VA_MAX_REG; \
sysv_varargs.__vr_top=SCRATCH + X64_VA_MAX_XMM; \
{ \
uint64_t *p = (uint64_t*)SCRATCH; \
p[0]=R_RDI; p[1]=R_RSI; p[2]=R_RDX; \
p[3]=R_RCX; p[4]=R_R8; p[5]=R_R9; \
memcpy(&p[6], emu->xmm, 8*16); \
#define CREATE_VALIST_FROM_VAARG(STACK, SCRATCH, N) \
va_list sysv_varargs; \
sysv_varargs.__gr_offs=-(6*8)+(8*(((N)<6)?(N):6)); \
sysv_varargs.__vr_offs=-(8*16); \
sysv_varargs.__stack=(STACK); \
sysv_varargs.__gr_top=(void*)((uintptr_t)(SCRATCH) + X64_VA_MAX_REG); \
sysv_varargs.__vr_top=(void*)((uintptr_t)(SCRATCH) + X64_VA_MAX_XMM); \
{ \
uintptr_t *p = (uintptr_t*)(SCRATCH); \
p[0]=R_RDI; p[1]=R_RSI; p[2]=R_RDX; \
p[3]=R_RCX; p[4]=R_R8; p[5]=R_R9; \
memcpy(&p[6], emu->xmm, 8*16); \
}
#elif defined(__powerpc64__)
@@ -100,6 +100,31 @@ typedef struct va_list {
#define CONVERT_VALIST(A) \
#error TODO!
#elif defined(__loongarch64)
#define CREATE_SYSV_VALIST(A) \
va_list sysv_varargs = (va_list)A
// not creating CONVERT_VALIST(A) on purpose
// this one will create a VA_LIST from x64_va_list using only GPRS and 100 stack element
#define CREATE_VALIST_FROM_VALIST(VA, SCRATCH) \
va_list sysv_varargs; \
{ \
uintptr_t *p = (uintptr_t*)(SCRATCH); \
int n = (X64_VA_MAX_REG - (VA)->gp_offset)/8; \
if(n) memcpy(&p[0], (VA)->reg_save_area, n*8); \
memcpy(&p[n], (VA)->overflow_arg_area, 100*8); \
sysv_varargs = (va_list)p; \
}
// this is an approximation, and if the va_list have some float/double, it will fail!
// if the funciton needs more than 100 args, it will also fail
#define CREATE_VALIST_FROM_VAARG(STACK, SCRATCH, N) \
va_list sysv_varargs; \
{ \
uintptr_t *p = (uintptr_t*)(SCRATCH); \
p[0]=R_RDI; p[1]=R_RSI; p[2]=R_RDX; \
p[3]=R_RCX; p[4]=R_R8; p[5]=R_R9; \
memcpy(&p[6], STACK, 100*8); \
sysv_varargs = (va_list)&p[N]; \
}
#else
#error Unknown architecture!
#endif
@@ -115,9 +140,14 @@ typedef struct x64emu_s x64emu_t;
// 1st pos is of vaarg is 0, not 1!
void myStackAlign(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* mystack, int xmm, int pos);
void myStackAlignScanf(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* mystack, int pos);
void myStackAlignGVariantNew(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* mystack, int xmm, int pos);
void myStackAlignW(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* mystack, int xmm, int pos);
void myStackAlignScanfW(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t* mystack, int pos);
#ifndef CONVERT_VALIST
void myStackAlignValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va);
void myStackAlignWValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va);
void myStackAlignScanfValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va);
void myStackAlignScanfWValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va);
#endif
struct x64_stat64 { /* x86_64 arm64 */
uint64_t st_dev; /* 0 */ /* 0 */
@@ -149,3 +179,5 @@ void AlignEpollEvent(void* dest, void* source, int nbr); // x86 -> Arm
void UnalignSemidDs(void *dest, const void* source);
void AlignSemidDs(void *dest, const void* source);
uintptr_t getVArgs(x64emu_t* emu, int pos, uintptr_t* b, int N);
+2 -4
View File
@@ -24,7 +24,6 @@
// *********** GTK *****************
#if 0
EXPORT void* gdk_display = NULL; // in case it's used...
void my_checkGlobalGdkDisplay()
@@ -38,7 +37,7 @@ void my_setGlobalGThreadsInit()
int val = 1;
uintptr_t globoffs, globend;
if (GetGlobalNoWeakSymbolStartEnd(my_context->maplib, "g_threads_got_initialized", &globoffs, &globend, -1, NULL)) {
printf_log(LOG_DEBUG, "Global g_threads_got_initialized workaround, @%p <= %p\n", (void*)globoffs, (void*)val);
printf_log(LOG_DEBUG, "Global g_threads_got_initialized workaround, @%p <= %d\n", (void*)globoffs, val);
memcpy((void*)globoffs, &val, sizeof(val));
}
}
@@ -50,14 +49,13 @@ void** my_GetGTKDisplay()
return &gdk_display;
char* name = getGDKX11LibName();
library_t * lib = GetLibInternal(name?name:"libgtk-1.2.so.0");
library_t * lib = GetLibInternal(name?name:"libgdk-x11-2.0.so.0");
if(!lib) return &gdk_display; // mmm, that will crash later probably
void* s = dlsym(GetHandle(lib), "gdk_display");
gdk_display = *(void**)s;
return s;
}
#endif
// **************** NCurses ****************
EXPORT int COLS;
EXPORT int LINES;
+14 -14
View File
@@ -451,8 +451,8 @@ static int GetGlobalSymbolStartEnd_internal(lib_t *maplib, const char* name, uin
// nope, not found
return 0;
}
//void** my_GetGTKDisplay();
//void** my_GetGthreadsGotInitialized();
void** my_GetGTKDisplay();
void** my_GetGthreadsGotInitialized();
int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, uintptr_t* end, elfheader_t* self, int version, const char* vername)
{
if(GetGlobalSymbolStartEnd_internal(maplib, name, start, end, self, version, vername)) {
@@ -470,18 +470,18 @@ int GetGlobalSymbolStartEnd(lib_t *maplib, const char* name, uintptr_t* start, u
return 1;
}
// some special case symbol, defined inside box64 itself
//if(!strcmp(name, "gdk_display")) {
// *start = (uintptr_t)my_GetGTKDisplay();
// *end = *start+sizeof(void*);
// printf_log(LOG_INFO, "Using global gdk_display for gdk-x11 (%p:%p)\n", start, *(void**)start);
// return 1;
//}
//if(!strcmp(name, "g_threads_got_initialized")) {
// *start = (uintptr_t)my_GetGthreadsGotInitialized();
// *end = *start+sizeof(int);
// printf_log(LOG_INFO, "Using global g_threads_got_initialized for gthread2 (%p:%p)\n", start, *(void**)start);
// return 1;
//}
if(!strcmp(name, "gdk_display")) {
*start = (uintptr_t)my_GetGTKDisplay();
*end = *start+sizeof(void*);
printf_log(LOG_INFO, "Using global gdk_display for gdk-x11 (%p:%p)\n", start, *(void**)start);
return 1;
}
if(!strcmp(name, "g_threads_got_initialized")) {
*start = (uintptr_t)my_GetGthreadsGotInitialized();
*end = *start+sizeof(int);
printf_log(LOG_INFO, "Using global g_threads_got_initialized for gthread2 (%p:%p)\n", start, *(void**)start);
return 1;
}
// not found...
return 0;
}
+22 -10
View File
@@ -98,22 +98,23 @@ GO("libuuid.so.1", libuuid)
GO("libresolv.so.2", libresolv)
GO("libpulse-simple.so.0", pulsesimple)
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("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)
//GO("libgobject-2.0.so.0", gobject2)
//GO("libglib-2.0.so.0", glib2)
//GO("libgthread-2.0.so.0", gthread2)
GO("libgdk_pixbuf-2.0.so.0", gdkpixbuf2)
GO("libgconf-2.so.4", gconf2)
GO("libgio-2.0.so.0", gio2)
GO("libgmodule-2.0.so.0", gmodule2)
GO("libgobject-2.0.so.0", gobject2)
GO("libglib-2.0.so.0", glib2)
GO("libgthread-2.0.so.0", gthread2)
//GO("libgstreamer-0.10.so.0", gstreamer010)
//GO("libgstinterfaces-0.10.so.0", gstinterfaces010)
//GO("libdbusmenu-gtk.so.4", dbusmenugtk)
//GO("libdbusmenu-glib.so.4", dbusmenuglib)
//GO("libdbus-glib-1.so.2", dbusglib1)
GO("libdbus-glib-1.so.2", dbusglib1)
//GO("libgudev-1.0.so.0", gudev1)
//GO("libappindicator.so.1", appindicator)
GO("libatk-1.0.so.0", atk)
@@ -135,6 +136,7 @@ GO("libSM.so.6", libsm)
GO("libICE.so.6", libice)
//GO("libusb-1.0.so.0", libusb1)
GO("libncursesw.so.5", libncursesw)
GO("libncursesw.so.6", libncursesw6)
GO("libform.so.5", libform)
GO("libformw.so.5", libformw)
GO("libncurses.so.5", libncurses)
@@ -162,6 +164,16 @@ GO("libgssapi_krb5.so.2", gssapikrb5)
GO("libgssapi.so.3", gssapi)
//GO("libtiff.so.5", libtiff)
//GO("libfuse.so.2", libfuse)
GO("libnss3.so", nss3)
GO("libnssutil3.so", nssutil3)
GO("libsmime3.so", smime3)
GO("libnspr4.so", nspr4)
GO("libplds4.so", plds4)
GO("libplc4.so", plc4)
GO("libssl3.so", ssl3)
GO("libnsl.so.1", nsl)
GO("libselinux.so.1", selinux)
GO("libsecret-1.so.0", secret1)
GO("ld-linux-x86-64.so.2", ldlinux)
+516 -184
View File
@@ -499,190 +499,6 @@ void myStackAlignScanfW(x64emu_t* emu, const char* fmt, uint64_t* st, uint64_t*
}
}
#if 0
void myStackAlignGVariantNew(const char* fmt, uint32_t* st, uint32_t* mystack)
{
if (!fmt)
return;
const char *p = fmt;
int state = 0;
int inblocks = 0;
int tmp;
do {
switch(state) {
case 0: // Nothing
switch(*p) {
case 'b': // gboolean
case 'y': // guchar
case 'n': // gint16
case 'q': // guint16
case 'i': // gint32
case 'u': // guint32
case 'h': // gint32
case 's': // const gchar*
case 'o':
case 'g':
case 'v': // GVariant*
case '*': // GVariant* of any type
case '?': // GVariant* of basic type
case 'r': // GVariant* of tuple type
*mystack = *st;
++mystack;
++st;
break;
case 'x': // gint64
case 't': // guint64
case 'd': // gdouble
if ((((uint32_t)mystack)&0x7)!=0)
++mystack;
*(uint64_t*)mystack = *(uint64_t*)st;
st+=2; mystack+=2;
break;
case '{':
case '(': ++inblocks; break;
case '}':
case ')': --inblocks; break;
case 'a': state = 1; break; // GVariantBuilder* or GVariantIter**
case 'm': state = 2; break; // maybe types
case '@': state = 3; break; // GVariant* of type [type]
case '^': state = 4; break; // pointer value
case '&': break; // pointer: do nothing
}
break;
case 1: // Arrays
switch(*p) {
case '{':
case '(': ++tmp; break;
case '}':
case ')': --tmp; break;
}
if (*p == 'a') break;
if (tmp == 0) {
*mystack = *st;
++mystack;
++st;
state = 0;
}
break;
case 2: // Maybe-types
switch(*p) {
case 'b': // gboolean
case 'y': // guchar
case 'n': // gint16
case 'q': // guint16
case 'i': // gint32
case 'u': // guint32
case 'h': // gint32
case 'x': // gint64
case 't': // guint64
case 'd': // gdouble
case '{':
case '}':
case '(':
case ')':
// Add a gboolean or gboolean*, no char increment
*mystack = *st;
++mystack;
++st;
--p;
state = 0;
break;
case 'a': // GVariantBuilder* or GVariantIter**
case 's': // const gchar*
case 'o':
case 'g':
case 'v': // GVariant*
case '@': // GVariant* of type [type]
case '*': // GVariant* of any type
case '?': // GVariant* of basic type
case 'r': // GVariant* of tuple type
case '&': // pointer
case '^': // pointer value
// Just maybe-NULL
--p;
state = 0;
break;
default: // Default to add a gboolean & reinit state?
*mystack = *st;
++mystack;
++st;
--p;
state = 0;
}
break;
case 3: // GVariant*
switch(*p) {
case '{':
case '(': ++tmp; break;
case '}':
case ')': --tmp; break;
case 'a': // GVariantBuilder* or GVariantIter**
do { ++p; } while(*p == 'a'); // Use next character which is not an array (array definition)
switch(*p) {
case '{':
case '(': ++tmp; break;
case '}':
case ')': --tmp; break;
}
break;
}
if (tmp == 0) {
*mystack = *st;
++mystack;
++st;
state = 0;
}
break;
case 4: // ^
if (*p == 'a') state = 5;
else if (*p == '&') state = 8;
else state = 0; //???
break;
case 5: // ^a
if ((*p == 's') || (*p == 'o') || (*p == 'y')) {
*mystack = *st;
++mystack;
++st;
state = 0;
} else if (*p == '&') state = 6;
else if (*p == 'a') state = 7;
else state = 0; //???
break;
case 6: // ^a&
if ((*p == 's') || (*p == 'o')) {
*mystack = *st;
++mystack;
++st;
state = 0;
} else if (*p == 'a') state = 7;
else state = 0; //???
break;
case 7: // ^aa / ^a&a
if (*p == 'y') {
*mystack = *st;
++mystack;
++st;
state = 0;
} else state = 0; //???
case 8: // ^&
if (*p == 'a') state = 9;
else state = 0; //???
case 9: // ^&a
if (*p == 'y') {
*mystack = *st;
++mystack;
++st;
state = 0;
} else state = 0; //???
}
++p;
} while (*p && (inblocks || state));
}
#endif
#undef st_atime
#undef st_mtime
@@ -801,3 +617,519 @@ void AlignSemidDs(void *dest, const void* source)
arm_struct->sem_ctime = x64_struct->sem_ctime;
arm_struct->sem_nsems = x64_struct->sem_nsems;
}
uintptr_t getVArgs(x64emu_t* emu, int pos, uintptr_t* b, int N)
{
if((pos+N)>5)
return b[pos+N-6];
return emu->regs[regs_abi[pos+N]].q[0];
}
#ifndef CONVERT_VALIST
void myStackAlignValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va)
{
if(!fmt)
return;
// loop...
const char* p = fmt;
int state = 0;
#ifndef HAVE_LD80BITS
double d;
long double ld;
#endif
int x = 0;
uintptr_t *area = (uintptr_t*)va->reg_save_area; // the direct registers copy
uintptr_t *st = (uintptr_t*)va->overflow_arg_area; // the stack arguments
uintptr_t gprs = va->gp_offset;
uintptr_t fprs = va->fp_offset;
while(*p)
{
switch(state) {
case 0:
switch(*p) {
case '%': state = 1; ++p; break;
default:
++p;
}
break;
case 1: // normal
case 2: // l
case 3: // ll
case 4: // L
case 5: // z
switch(*p) {
case '%': state = 0; ++p; break; //%% = back to 0
case 'l': ++state; if (state>3) state=3; ++p; break;
case 'L': state = 4; ++p; break;
case 'z': state = 5; ++p; break;
case 'a':
case 'A':
case 'e':
case 'E':
case 'g':
case 'G':
case 'F':
case 'f': state += 10; break; // float
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X': state += 20; break; // int
case 'h': ++p; break; // ignored...
case '\'':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
case '+':
case '-': ++p; break; // formating, ignored
case 'm': state = 0; ++p; break; // no argument
case 'n':
case 'p':
case 'S':
case 's': state = 30; break; // pointers
case '$': ++p; break; // should issue a warning, it's not handled...
case '*':
if(gprs<X64_VA_MAX_REG) {
*mystack = area[gprs/8];
gprs+=8;
} else {
*mystack = *st;
++st;
}
++mystack;
++p;
break; // fetch an int in the stack....
case ' ': state=0; ++p; break;
default:
state=20; // other stuff, put an int...
}
break;
case 11: //double
case 12: //%lg, still double
case 13: //%llg, still double
case 15: //%zg, meh.. double?
if(fprs<X64_VA_MAX_XMM) {
*mystack = area[fprs/8];
fprs+=8;
mystack++;
} else {
*mystack = *st;
st++; mystack++;
}
state = 0;
++p;
break;
case 14: //%LG long double
if((((uintptr_t)st)&0xf)!=0)
st++;
#ifdef HAVE_LD80BITS
if((((uintptr_t)mystack)&0xf)!=0)
mystack++;
memcpy(mystack, st, 16);
st+=2; mystack+=2;
#else
// there is 128bits long double on ARM64, but they need 128bit alignment
if((((uintptr_t)mystack)&0xf)!=0)
mystack++;
LD2D((void*)st, &d);
ld = d ;
memcpy(mystack, &ld, 16);
st+=2; mystack+=2;
#endif
state = 0;
++p;
break;
case 20: // fallback
case 21:
case 22:
case 23: // 64bits int
case 24: // normal int / pointer
case 25: // size_t int
case 30:
if(gprs<X64_VA_MAX_REG) {
*mystack = area[gprs/8];
gprs+=8;
} else {
*mystack = *st;
++st;
}
++mystack;
state = 0;
++p;
break;
default:
// whaaaat?
state = 0;
}
}
}
void myStackAlignWValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va)
{
// loop...
const wchar_t* p = (const wchar_t*)fmt;
int state = 0;
#ifndef HAVE_LD80BITS
double d;
long double ld;
#endif
int x = 0;
uintptr_t *area = (uintptr_t*)va->reg_save_area; // the direct registers copy
uintptr_t *st = (uintptr_t*)va->overflow_arg_area; // the stack arguments
uintptr_t gprs = va->gp_offset;
uintptr_t fprs = va->fp_offset;
while(*p)
{
switch(state) {
case 0:
switch(*p) {
case '%': state = 1; ++p; break;
default:
++p;
}
break;
case 1: // normal
case 2: // l
case 3: // ll
case 4: // L
case 5: // z
switch(*p) {
case '%': state = 0; ++p; break; //%% = back to 0
case 'l': ++state; if (state>3) state=3; ++p; break;
case 'L': state = 4; ++p; break;
case 'z': state = 5; ++p; break;
case 'a':
case 'A':
case 'e':
case 'E':
case 'g':
case 'G':
case 'F':
case 'f': state += 10; break; // float
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X': state += 20; break; // int
case 'h': ++p; break; // ignored...
case '\'':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
case '+':
case '-': ++p; break; // formating, ignored
case 'm': state = 0; ++p; break; // no argument
case 'n':
case 'p':
case 'S':
case 's': state = 30; break; // pointers
case '$': ++p; break; // should issue a warning, it's not handled...
case '*':
if(gprs<X64_VA_MAX_REG) {
*mystack = area[gprs/8];
gprs+=8;
} else {
*mystack = *st;
++st;
}
++mystack;
++p;
break; // fetch an int in the stack....
case ' ': state=0; ++p; break;
default:
state=20; // other stuff, put an int...
}
break;
case 11: //double
case 12: //%lg, still double
case 13: //%llg, still double
case 15: //%zg, meh .. double
if(fprs<X64_VA_MAX_XMM) {
*mystack = area[fprs/8];
fprs+=8;
mystack++;
} else {
*mystack = *st;
st++; mystack++;
}
state = 0;
++p;
break;
case 14: //%LG long double
if((((uintptr_t)st)&0xf)!=0)
st++;
#ifdef HAVE_LD80BITS
if((((uintptr_t)mystack)&0xf)!=0)
mystack++;
memcpy(mystack, st, 16);
st+=2; mystack+=2;
#else
// there is 128bits long double on ARM64, but they need 128bit alignment
if((((uintptr_t)mystack)&0xf)!=0)
mystack++;
LD2D((void*)st, &d);
ld = d ;
memcpy(mystack, &ld, 16);
st+=2; mystack+=2;
#endif
state = 0;
++p;
break;
case 20: // fallback
case 21:
case 22:
case 23: // 64bits int
case 24: // normal int / pointer
case 25: // size_t int
case 30:
if(gprs<X64_VA_MAX_REG) {
*mystack = area[gprs/8];
gprs+=8;
} else {
*mystack = *st;
++st;
}
++mystack;
state = 0;
++p;
break;
default:
// whaaaattt?
state = 0;
}
}
}
void myStackAlignScanfValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va)
{
if(!fmt)
return;
// loop...
const char* p = fmt;
int state = 0;
int ign = 0;
uintptr_t *area = (uintptr_t*)va->reg_save_area; // the direct registers copy
uintptr_t *st = (uintptr_t*)va->overflow_arg_area; // the stack arguments
uintptr_t gprs = va->gp_offset;
uintptr_t fprs = va->fp_offset;
while(*p)
{
switch(state) {
case 0:
ign = 0;
switch(*p) {
case '%': state = 1; ++p; break;
default:
++p;
}
break;
case 1: // normal
case 2: // l
case 3: // ll
case 4: // L
case 5: // z
switch(*p) {
case '%': state = 0; ++p; break; //%% = back to 0
case 'l': ++state; if (state>3) state=3; ++p; break;
case 'L': state = 4; ++p; break;
case 'z': state = 5; ++p; break;
case 'a':
case 'A':
case 'e':
case 'E':
case 'g':
case 'G':
case 'F':
case 'f': state += 10; break; // float
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X': state += 20; break; // int
case 'h': ++p; break; // ignored...
case '\'':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
case '+':
case '-': ++p; break; // formating, ignored
case 'm': state = 0; ++p; break; // no argument
case 'n':
case 'p':
case 'S':
case 's': state = 30; break; // pointers
case '$': ++p; break; // should issue a warning, it's not handled...
case '*': ign=1; ++p; break; // ignore arg
case ' ': state=0; ++p; break;
default:
state=20; // other stuff, put an int...
}
break;
case 11: //double
case 12: //%lg, still double
case 13: //%llg, still double
case 14: //%Lg long double
case 15: //%zg
case 20: // fallback
case 21:
case 22:
case 23: // 64bits int
case 24: // normal int / pointer
case 25: // size_t int
case 30:
if(!ign) {
if(gprs<X64_VA_MAX_REG) {
*mystack = area[gprs/8];
gprs+=8;
} else {
*mystack = *st;
++st;
}
++mystack;
}
state = 0;
++p;
break;
default:
// whaaaat?
state = 0;
}
}
}
void myStackAlignScanfWValist(x64emu_t* emu, const char* fmt, uint64_t* mystack, x64_va_list_t va)
{
if(!fmt)
return;
// loop...
const wchar_t* p = (const wchar_t*)fmt;
int state = 0;
int ign = 0;
uintptr_t *area = (uintptr_t*)va->reg_save_area; // the direct registers copy
uintptr_t *st = (uintptr_t*)va->overflow_arg_area; // the stack arguments
uintptr_t gprs = va->gp_offset;
uintptr_t fprs = va->fp_offset;
while(*p)
{
switch(state) {
case 0:
ign = 0;
switch(*p) {
case '%': state = 1; ++p; break;
default:
++p;
}
break;
case 1: // normal
case 2: // l
case 3: // ll
case 4: // L
case 5: // z
switch(*p) {
case '%': state = 0; ++p; break; //%% = back to 0
case 'l': ++state; if (state>3) state=3; ++p; break;
case 'L': state = 4; ++p; break;
case 'z': state = 5; ++p; break;
case 'a':
case 'A':
case 'e':
case 'E':
case 'g':
case 'G':
case 'F':
case 'f': state += 10; break; // float
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X': state += 20; break; // int
case 'h': ++p; break; // ignored...
case '\'':
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
case '.':
case '+':
case '-': ++p; break; // formating, ignored
case 'm': state = 0; ++p; break; // no argument
case 'n':
case 'p':
case 'S':
case 's': state = 30; break; // pointers
case '$': ++p; break; // should issue a warning, it's not handled...
case '*': ign = 1; ++p; break; // ignore arg
case ' ': state=0; ++p; break;
default:
state=20; // other stuff, put an int...
}
break;
case 11: //double
case 12: //%lg, still double
case 13: //%llg, still double
case 14: //%Lg long double
case 15: //%zg
case 20: // fallback
case 21:
case 22:
case 23: // 64bits int
case 24: // normal int / pointer
case 25: // size_t int
case 30:
if(!ign) {
if(gprs<X64_VA_MAX_REG) {
*mystack = area[gprs/8];
gprs+=8;
} else {
*mystack = *st;
++st;
}
++mystack;
}
state = 0;
++p;
break;
default:
// whaaaat?
state = 0;
}
}
}
#endif
+7 -4
View File
@@ -290,7 +290,7 @@ uint64_t RunFunctionHandler(int* exit, x64_ucontext_t* sigcontext, uintptr_t fnc
emu->segs_serial[i] = 0;
if(nargs>6)
R_RSP -= (nargs-6)*4; // need to push in reverse order
R_RSP -= (nargs-6)*sizeof(void*); // need to push in reverse order
uint64_t *p = (uint64_t*)R_RSP;
@@ -310,10 +310,10 @@ uint64_t RunFunctionHandler(int* exit, x64_ucontext_t* sigcontext, uintptr_t fnc
int oldquitonlongjmp = emu->quitonlongjmp;
emu->quitonlongjmp = 2;
//EmuCall(emu, fnc); // avoid DynaCall for now
DynaCall(emu, fnc);
EmuCall(emu, fnc); // avoid DynaCall for now
//DynaCall(emu, fnc);
if(nargs>6)
R_RSP+=((nargs-6)*4);
R_RSP+=((nargs-6)*sizeof(void*));
emu->quitonlongjmp = oldquitonlongjmp;
@@ -736,6 +736,8 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
int Locks = unlockMutex();
uint32_t prot = getProtection((uintptr_t)addr);
#ifdef DYNAREC
if((Locks & (1<<8)) && (sig==SIGSEGV)) //1<<8 is building_dynablock
cancelFillBlock(); // Segfault inside a Fillblock, just cancel it's creation, don't relock mutexes
dynablock_t* db = NULL;
int db_searched = 0;
if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && (prot&PROT_DYNAREC)) {
@@ -805,6 +807,7 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
glitch_pc = pc;
glitch_addr = addr;
glitch_prot = prot;
cleanDBFromAddressRange(((uintptr_t)addr)&~0xfff, 0x1000, 0);
relockMutex(Locks);
return; // try again
}
+17 -4
View File
@@ -8,6 +8,7 @@
#include <errno.h>
#include <setjmp.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include "debug.h"
#include "box64context.h"
@@ -28,8 +29,12 @@
#include "dynablock.h"
#endif
void _pthread_cleanup_push_defer(void* buffer, void* routine, void* arg); // declare hidden functions
void _pthread_cleanup_pop_restore(void* buffer, int exec);
//void _pthread_cleanup_push_defer(void* buffer, void* routine, void* arg); // declare hidden functions
//void _pthread_cleanup_pop_restore(void* buffer, int exec);
typedef void (*vFppp_t)(void*, void*, void*);
typedef void (*vFpi_t)(void*, int);
static vFppp_t real_pthread_cleanup_push_defer = NULL;
static vFpi_t real_pthread_cleanup_pop_restore = NULL;
void _pthread_cleanup_push(void* buffer, void* routine, void* arg); // declare hidden functions
void _pthread_cleanup_pop(void* buffer, int exec);
@@ -417,6 +422,11 @@ EXPORT int my_pthread_attr_setstackaddr(x64emu_t* emu, pthread_attr_t* attr, voi
return pthread_attr_setstack(getAlignedAttr(attr), addr, size);
//return pthread_attr_setstackaddr(getAlignedAttr(attr), addr);
}
EXPORT int my_pthread_getattr_np(x64emu_t* emu, pthread_t thread_id, pthread_attr_t* attr)
{
(void)emu;
return pthread_getattr_np(thread_id, getAlignedAttrWithInit(attr, 0));
}
#endif
EXPORT int my_pthread_create(x64emu_t *emu, void* t, void* attr, void* start_routine, void* arg)
@@ -663,7 +673,7 @@ EXPORT int my_pthread_cond_wait(x64emu_t* emu, pthread_cond_t* cond, void* mutex
EXPORT void my__pthread_cleanup_push_defer(x64emu_t* emu, void* buffer, void* routine, void* arg)
{
(void)emu;
_pthread_cleanup_push_defer(buffer, findcleanup_routineFct(routine), arg);
real_pthread_cleanup_push_defer(buffer, findcleanup_routineFct(routine), arg);
}
EXPORT void my__pthread_cleanup_push(x64emu_t* emu, void* buffer, void* routine, void* arg)
@@ -675,7 +685,7 @@ EXPORT void my__pthread_cleanup_push(x64emu_t* emu, void* buffer, void* routine,
EXPORT void my__pthread_cleanup_pop_restore(x64emu_t* emu, void* buffer, int exec)
{
(void)emu;
_pthread_cleanup_pop_restore(buffer, exec);
real_pthread_cleanup_pop_restore(buffer, exec);
}
EXPORT void my__pthread_cleanup_pop(x64emu_t* emu, void* buffer, int exec)
@@ -1130,6 +1140,9 @@ emu_jmpbuf_t* GetJmpBuf()
void init_pthread_helper()
{
real_pthread_cleanup_push_defer = (vFppp_t)dlsym(NULL, "_pthread_cleanup_push_defer");
real_pthread_cleanup_pop_restore = (vFpi_t)dlsym(NULL, "_pthread_cleanup_pop_restore");
InitCancelThread();
pthread_key_create(&jmpbuf_key, emujmpbuf_destroy);
}
+328
View File
@@ -0,0 +1,328 @@
#include "mailbox.h"
#include <semaphore.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include "custommem.h"
#include "debug.h"
//#define DEBUG_MAILBOX
// === REQUESTS ===
typedef enum available_bits_s {
AVAILABLE_BITS_32 = 32,
AVAILABLE_BITS_47 = 47,
AVAILABLE_BITS_MAX = 0,
} available_bits_e;
typedef struct request_s {
enum request_type_e {
REQUEST_HALT,
REQUEST_UPD_PROTECT,
REQUEST_SET_PROTECT,
REQUEST_FRE_PROTECT,
REQUEST_GET_PROTECT,
REQUEST_LOD_PROTECT,
#ifdef DYNAREC
REQUEST_PROT_DB,
REQUEST_UNPROT_DB,
REQUEST_ISPROT_DB,
#endif
REQUEST_FIND,
REQUEST_FIND_HINT,
} type;
sem_t *answered;
void *ansBuf;
union {
struct {
uintptr_t addr;
} protect;
struct {
uintptr_t addr;
size_t size;
} size_protect;
struct {
uintptr_t addr;
size_t size;
uint32_t prot;
} prot_protect;
struct {
available_bits_e availablebits;
uintptr_t size;
} find;
struct {
available_bits_e availablebits;
uintptr_t size;
void* hint;
} find_near;
} data;
#ifdef DEBUG_MAILBOX
int reqno;
#endif
} request_t;
request_t curHdr;
sem_t empty;
sem_t full;
sem_t finished;
static void sendRequest(request_t *rhdr, void *ans) {
#ifdef DEBUG_MAILBOX
static int reqno = 0;
rhdr->reqno = ++reqno;
printf_log(LOG_DEBUG, "[REQ%05u] Sending request %02X (ans=%p)\n", rhdr->reqno, rhdr->type, ans);
#endif
rhdr->ansBuf = ans;
if (ans) {
sem_t answered;
sem_init(&answered, 0, 0);
rhdr->answered = &answered;
#ifdef DEBUG_MAILBOX
printf_log(LOG_DEBUG, "[REQ%05u] Will wait for answer\n", rhdr->reqno);
#endif
sem_wait(&empty);
curHdr = *rhdr;
sem_post(&full);
sem_wait(&answered);
} else {
sem_wait(&empty);
curHdr = *rhdr;
sem_post(&full);
}
#ifdef DEBUG_MAILBOX
printf_log(LOG_DEBUG, "[REQ%05u] Done, leaving\n", rhdr->reqno);
#endif
}
// A function per request (avoids exposing dangerous internal functions)
void updateProtection(uintptr_t addr, size_t size, uint32_t prot) {
request_t req;
req.type = REQUEST_UPD_PROTECT;
req.data.prot_protect.addr = addr;
req.data.prot_protect.size = size;
req.data.prot_protect.prot = prot;
void *none = NULL;
sendRequest(&req, &none); // Need to wait for completion
}
void setProtection(uintptr_t addr, size_t size, uint32_t prot) {
request_t req;
req.type = REQUEST_SET_PROTECT;
req.data.prot_protect.addr = addr;
req.data.prot_protect.size = size;
req.data.prot_protect.prot = prot;
sendRequest(&req, NULL);
}
void freeProtection(uintptr_t addr, size_t size) {
request_t req;
req.type = REQUEST_FRE_PROTECT;
req.data.size_protect.addr = addr;
req.data.size_protect.size = size;
void *none = NULL;
sendRequest(&req, &none); // Need to wait for completion
}
uint32_t getProtection(uintptr_t addr) {
request_t req;
req.type = REQUEST_GET_PROTECT;
req.data.protect.addr = addr;
uint32_t ret;
sendRequest(&req, &ret);
return ret;
}
void loadProtectionFromMap() {
request_t req;
req.type = REQUEST_LOD_PROTECT;
void *none = NULL;
sendRequest(&req, &none); // Need to wait for completion
}
#ifdef DYNAREC
void protectDB(uintptr_t addr, size_t size) {
request_t req;
req.type = REQUEST_PROT_DB;
req.data.size_protect.addr = addr;
req.data.size_protect.size = size;
void *none = NULL;
sendRequest(&req, &none); // Need to wait for completion
}
void unprotectDB(uintptr_t addr, size_t size) {
request_t req;
req.type = REQUEST_UNPROT_DB;
req.data.size_protect.addr = addr;
req.data.size_protect.size = size;
void *none = NULL;
sendRequest(&req, &none); // Need to wait for completion
}
int isprotectedDB(uintptr_t addr, size_t size) {
request_t req;
req.type = REQUEST_ISPROT_DB;
req.data.size_protect.addr = addr;
req.data.size_protect.size = size;
int ret;
sendRequest(&req, &ret);
return ret;
}
#endif
void* find32bitBlock(size_t size) {
request_t req;
req.type = REQUEST_FIND;
req.data.find.size = size;
req.data.find.availablebits = AVAILABLE_BITS_32;
void* ret;
sendRequest(&req, &ret);
return ret;
}
void* findBlockNearHint(void* hint, size_t size) {
request_t req;
req.type = REQUEST_FIND_HINT;
req.data.find_near.size = size;
req.data.find_near.availablebits = AVAILABLE_BITS_MAX;
req.data.find_near.hint = hint;
void* ret;
sendRequest(&req, &ret);
return ret;
}
void* find47bitBlock(size_t size) {
request_t req;
req.type = REQUEST_FIND;
req.data.find.size = size;
req.data.find.availablebits = AVAILABLE_BITS_47;
void* ret;
sendRequest(&req, &ret);
return ret;
}
void* find47bitBlockNearHint(void* hint, size_t size) {
request_t req;
req.type = REQUEST_FIND_HINT;
req.data.find_near.size = size;
req.data.find_near.availablebits = AVAILABLE_BITS_47;
req.data.find_near.hint = hint;
void* ret;
sendRequest(&req, &ret);
return ret;
}
// === MAILBOX ===
void internalUpdateProtection(uintptr_t addr, size_t size, uint32_t prot);
void internalSetProtection(uintptr_t addr, size_t size, uint32_t prot);
void internalFreeProtection(uintptr_t addr, size_t size);
uint32_t internalGetProtection(uintptr_t addr);
void internalLoadProtectionFromMap();
#ifdef DYNAREC
void internalProtectDB(uintptr_t addr, size_t size);
void internalUnprotectDB(uintptr_t addr, size_t size);
int internalIsprotectedDB(uintptr_t addr, size_t size);
#endif
void* internalFind32bitBlock(size_t size);
void* internalFindBlockNearHint(void* hint, size_t size);
void* internalFind47bitBlock(size_t size);
void* internalFind47bitBlockNearHint(void* hint, size_t size);
void *parse_find_req(request_t *req) {
switch (req->data.find.availablebits) {
case AVAILABLE_BITS_32:
return internalFind32bitBlock(req->data.find.size);
case AVAILABLE_BITS_47:
return internalFind47bitBlock(req->data.find.size);
}
__builtin_unreachable();
}
void *parse_find_near_req(request_t *req) {
switch (req->data.find_near.availablebits) {
case AVAILABLE_BITS_MAX:
return internalFindBlockNearHint(req->data.find_near.hint, req->data.find_near.size);
case AVAILABLE_BITS_47:
return internalFind47bitBlockNearHint(req->data.find_near.hint, req->data.find_near.size);
}
__builtin_unreachable();
}
static void runMailbox() {
sem_init(&empty, 0, 1);
sem_init(&full, 0, 0);
while (1) {
sem_wait(&full);
#ifdef DEBUG_MAILBOX
printf_log(LOG_DEBUG, "[ WORKER ] Received request %05u (%02X) (ans=%p)\n", curHdr.reqno, curHdr.type, curHdr.ansBuf);
#endif
switch (curHdr.type) {
case REQUEST_HALT:
return;
case REQUEST_UPD_PROTECT:
internalUpdateProtection(curHdr.data.prot_protect.addr, curHdr.data.prot_protect.size, curHdr.data.prot_protect.prot);
break;
case REQUEST_SET_PROTECT:
internalSetProtection(curHdr.data.prot_protect.addr, curHdr.data.prot_protect.size, curHdr.data.prot_protect.prot);
break;
case REQUEST_FRE_PROTECT:
internalFreeProtection(curHdr.data.size_protect.addr, curHdr.data.size_protect.size);
break;
case REQUEST_GET_PROTECT:
*(uintptr_t*)curHdr.ansBuf = internalGetProtection(curHdr.data.protect.addr);
break;
case REQUEST_LOD_PROTECT:
internalLoadProtectionFromMap();
break;
#ifdef DYNAREC
case REQUEST_PROT_DB:
internalProtectDB(curHdr.data.size_protect.addr, curHdr.data.size_protect.size);
break;
case REQUEST_UNPROT_DB:
internalUnprotectDB(curHdr.data.size_protect.addr, curHdr.data.size_protect.size);
break;
case REQUEST_ISPROT_DB:
*(intptr_t*)curHdr.ansBuf = internalIsprotectedDB(curHdr.data.size_protect.addr, curHdr.data.size_protect.size);
break;
#endif
case REQUEST_FIND:
*(void**)curHdr.ansBuf = parse_find_req(&curHdr);
break;
case REQUEST_FIND_HINT:
*(void**)curHdr.ansBuf = parse_find_near_req(&curHdr);
break;
#ifdef DEBUG_MAILBOX
default:
printf_log(LOG_DEBUG, "[ WORKER ] AAAAAAA %X\n", curHdr.type);
#endif
}
if (curHdr.ansBuf) {
#ifdef DEBUG_MAILBOX
printf_log(LOG_DEBUG, "[ WORKER ] Answering %X to REQ%05u\n", *(uintptr_t*)curHdr.ansBuf, curHdr.reqno);
#endif
sem_post(curHdr.answered);
}
sem_post(&empty);
#ifdef DEBUG_MAILBOX
printf_log(LOG_DEBUG, "[ WORKER ] Waiting for next request\n");
#endif
}
sem_destroy(&empty);
sem_destroy(&full);
}
#include <pthread.h>
#include <signal.h>
pthread_t thread;
static void *mailboxRoutine(void *arg) {
sigset_t sigset;
sigfillset(&sigset);
pthread_sigmask(SIG_BLOCK, &sigset, NULL);
runMailbox();
return NULL;
}
// Declared in main.c and threads.c
void startMailbox(void) {
pthread_create(&thread, NULL, mailboxRoutine, NULL);
}
void haltMailbox(void) {
request_t hltreq;
hltreq.type = REQUEST_HALT;
sendRequest(&hltreq, NULL);
pthread_join(thread, NULL);
}
+23
View File
@@ -0,0 +1,23 @@
#ifndef __MAILBOX_H__
#define __MAILBOX_H__
#include <stddef.h>
#include <stdint.h>
typedef struct dynablock_s dynablock_t;
//void updateProtection(uintptr_t addr, size_t size, uint32_t prot);
//void setProtection(uintptr_t addr, size_t size, uint32_t prot);
//void freeProtection(uintptr_t addr, size_t size);
//uint32_t getProtection(uintptr_t addr);
//void loadProtectionFromMap();
//#ifdef DYNAREC
//void protectDB(uintptr_t addr, size_t size);
//void unprotectDB(uintptr_t addr, size_t size);
//int isprotectedDB(uintptr_t addr, size_t size);
//#endif
//void* find32bitBlock(size_t size);
//void* findBlockNearHint(void* hint, size_t size);
//void* find47bitBlock(size_t size);
//void* find47bitBlockNearHint(void* hint, size_t size);
#endif // __MAILBOX_H__
+34 -8
View File
@@ -32,6 +32,9 @@
#include "x64run.h"
#include "symbols.h"
void startMailbox(void);
void haltMailbox(void);
box64context_t *my_context = NULL;
int box64_log = LOG_INFO; //LOG_NONE;
int box64_dump = 0;
@@ -49,6 +52,7 @@ int arm64_asimd = 0;
int arm64_aes = 0;
int arm64_pmull = 0;
int arm64_crc32 = 0;
int arm64_atomics = 0;
#endif
#else //DYNAREC
int box64_dynarec = 0;
@@ -92,14 +96,21 @@ void openFTrace()
char tmp[500];
char* p = t;
if(p && strstr(t, "%pid")) {
strcpy(tmp, p);
char* c = strstr(tmp, "%pid");
*c = 0; // cut
char pid[10];
sprintf(pid, "%d", getpid());
strcat(tmp, pid);
c = strstr(p, "%pid") + strlen("%pid");
strcat(tmp, c);
int next = 0;
do {
strcpy(tmp, p);
char* c = strstr(tmp, "%pid");
*c = 0; // cut
char pid[16];
if(next)
sprintf(pid, "%d-%d", getpid(), next);
else
sprintf(pid, "%d", getpid());
strcat(tmp, pid);
c = strstr(p, "%pid") + strlen("%pid");
strcat(tmp, c);
++next;
} while (FileExist(tmp, IS_FILE));
p = tmp;
ftrace_has_pid = 1;
}
@@ -149,6 +160,8 @@ void GatherDynarecExtensions()
arm64_pmull = 1;
if(hwcap&HWCAP_AES)
arm64_aes = 1;
if(hwcap&HWCAP_ATOMICS)
arm64_atomics = 1;
printf_log(LOG_INFO, "Dynarec for ARM64, with extension: ASIMD");
if(arm64_aes)
printf_log(LOG_INFO, " AES");
@@ -156,6 +169,8 @@ void GatherDynarecExtensions()
printf_log(LOG_INFO, " CRC32");
if(arm64_pmull)
printf_log(LOG_INFO, " PMULL");
if(arm64_atomics)
printf_log(LOG_INFO, " ATOMICS");
printf_log(LOG_INFO, " PageSize:%d\n", box64_pagesize);
#endif
}
@@ -699,6 +714,7 @@ void endBox64()
int running = 1;
int attempt = 0;
printf_log(LOG_DEBUG, "Waiting for all threads to finish before unloading box64context\n");
haltMailbox();
while(running) {
DIR *proc_dir;
char dirname[100];
@@ -731,7 +747,9 @@ void endBox64()
}
}
// all done, free context
startMailbox(); // Need to restart mailbox (to use protections)
FreeBox64Context(&my_context);
haltMailbox();
if(libGL) {
free(libGL);
libGL = NULL;
@@ -790,6 +808,9 @@ int main(int argc, const char **argv, const char **env) {
}
if(!box64_nobanner)
PrintBox64Version();
startMailbox();
// precheck, for win-preload
if(strstr(prog, "wine-preloader")==(prog+strlen(prog)-strlen("wine-preloader"))
|| strstr(prog, "wine64-preloader")==(prog+strlen(prog)-strlen("wine64-preloader"))) {
@@ -911,6 +932,11 @@ int main(int argc, const char **argv, const char **env) {
printf_log(LOG_INFO, "steam-runtime-check-requirements detected, faking All is good!\n");
exit(0); // exiting, not testing anything
}
// special case for steam-runtime-check-requirements to fake 64bits suport
if(strstr(prgname, "steamwebhelper")==prgname) {
printf_log(LOG_INFO, "steamwebhelper, ignoring for now!\n");
exit(0); // exiting
}
// special case for UnrealLinux.bin, it doesn't like "full path resolution"
if(!strcmp(prog, "UnrealLinux.bin") && my_context->argv[0]) {
free(my_context->argv[0]);
+11 -2
View File
@@ -4,7 +4,9 @@
#include <string.h>
#include <dlfcn.h>
#include <pthread.h>
#include <sys/mman.h>
#include <wrappedlibs.h>
#include "custommem.h"
#include "bridge.h"
#include "bridge_private.h"
@@ -33,12 +35,18 @@ typedef struct bridge_s {
kh_bridgemap_t *bridgemap;
} bridge_t;
// from src/wrapped/wrappedlibc.c
void* my_mmap(x64emu_t* emu, void* addr, unsigned long length, int prot, int flags, int fd, int64_t offset);
int my_munmap(x64emu_t* emu, void* addr, unsigned long length);
brick_t* NewBrick()
{
brick_t* ret = (brick_t*)calloc(1, sizeof(brick_t));
if(posix_memalign((void**)&ret->b, box64_pagesize, NBRICK*sizeof(onebridge_t))) {
void* ptr = my_mmap(thread_get_emu(), NULL, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE, MAP_PRIVATE | 0x40 | MAP_ANONYMOUS, -1, 0); // 0x40 is MAP_32BIT
if(ptr == MAP_FAILED) {
printf_log(LOG_NONE, "Warning, cannot allocate 0x%lx aligned bytes for bridge, will probably crash later\n", NBRICK*sizeof(onebridge_t));
}
ret->b = ptr;
return ret;
}
@@ -56,13 +64,14 @@ void FreeBridge(bridge_t** bridge)
if(!bridge || !*bridge)
return;
brick_t *b = (*bridge)->head;
x64emu_t* emu = thread_get_emu();
while(b) {
brick_t *n = b->next;
#ifdef DYNAREC
if(getProtection((uintptr_t)b->b)&PROT_DYNAREC)
unprotectDB((uintptr_t)b->b, NBRICK*sizeof(onebridge_t));
#endif
free(b->b);
my_munmap(emu, b->b, NBRICK*sizeof(onebridge_t));
free(b);
b = n;
}
+4 -4
View File
@@ -21,7 +21,7 @@ uint64_t RunFunction(box64context_t *context, uintptr_t fnc, int nargs, ...)
x64emu_t *emu = thread_get_emu();
if(nargs>6)
R_ESP -= (nargs-6)*4; // need to push in reverse order
R_ESP -= (nargs-6)*sizeof(void*); // need to push in reverse order
uint64_t *p = (uint64_t*)R_RSP;
@@ -40,7 +40,7 @@ uint64_t RunFunction(box64context_t *context, uintptr_t fnc, int nargs, ...)
DynaCall(emu, fnc);
if(nargs>6)
R_ESP+=((nargs-6)*4);
R_ESP+=((nargs-6)*sizeof(void*));
uint64_t ret = R_RAX;
@@ -51,7 +51,7 @@ EXPORTDYN
uint64_t RunFunctionWithEmu(x64emu_t *emu, int QuitOnLongJump, uintptr_t fnc, int nargs, ...)
{
if(nargs>6)
R_ESP -= (nargs-6)*4; // need to push in reverse order
R_ESP -= (nargs-6)*sizeof(void*); // need to push in reverse order
uint64_t *p = (uint64_t*)R_RSP;
@@ -78,7 +78,7 @@ uint64_t RunFunctionWithEmu(x64emu_t *emu, int QuitOnLongJump, uintptr_t fnc, in
DynaCall(emu, fnc);
if(oldip==R_RIP && nargs>6)
R_ESP+=((nargs-6)*4); // restore stack only if EIP is the one expected (else, it means return value is not the one expected)
R_ESP+=((nargs-6)*sizeof(void*)); // restore stack only if EIP is the one expected (else, it means return value is not the one expected)
emu->quit = old_quit;
emu->quitonlongjmp = oldlong;
+1537
View File
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappeddbusglib1DEFS_H_
#define __wrappeddbusglib1DEFS_H_
#endif // __wrappeddbusglib1DEFS_H_
@@ -0,0 +1,28 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappeddbusglib1TYPES_H_
#define __wrappeddbusglib1TYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
typedef void (*vFppp_t)(void*, void*, void*);
typedef void (*vFpppp_t)(void*, void*, void*, void*);
typedef void (*vFppppp_t)(void*, void*, void*, void*, void*);
typedef void* (*pFpppppiV_t)(void*, void*, void*, void*, void*, int64_t, ...);
typedef void* (*pFpppppiiV_t)(void*, void*, void*, void*, void*, int64_t, int64_t, ...);
#define SUPER() ADDED_FUNCTIONS() \
GO(dbus_g_type_collection_value_iterate, vFppp_t) \
GO(dbus_g_type_map_value_iterate, vFppp_t) \
GO(dbus_g_proxy_disconnect_signal, vFpppp_t) \
GO(dbus_g_proxy_connect_signal, vFppppp_t) \
GO(dbus_g_proxy_begin_call, pFpppppiV_t) \
GO(dbus_g_proxy_begin_call_with_timeout, pFpppppiiV_t)
#endif // __wrappeddbusglib1TYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappeddbusglib1UNDEFS_H_
#define __wrappeddbusglib1UNDEFS_H_
#endif // __wrappeddbusglib1UNDEFS_H_
+4
View File
@@ -12,6 +12,8 @@
#endif
typedef void (*vFppp_t)(void*, void*, void*);
typedef int64_t (*iFpiV_t)(void*, int64_t, ...);
typedef int64_t (*iFpiA_t)(void*, int64_t, va_list);
typedef void (*vFpppp_t)(void*, void*, void*, void*);
typedef int64_t (*iFpipp_t)(void*, int64_t, void*, void*);
typedef int64_t (*iFppip_t)(void*, void*, int64_t, void*);
@@ -24,6 +26,8 @@ typedef int64_t (*iFpppppp_t)(void*, void*, void*, void*, void*, void*);
GO(dbus_connection_remove_filter, vFppp_t) \
GO(dbus_timeout_set_data, vFppp_t) \
GO(dbus_watch_set_data, vFppp_t) \
GO(dbus_message_append_args, iFpiV_t) \
GO(dbus_message_append_args_valist, iFpiA_t) \
GO(dbus_connection_set_dispatch_status_function, vFpppp_t) \
GO(dbus_connection_set_wakeup_main_function, vFpppp_t) \
GO(dbus_connection_set_data, iFpipp_t) \
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgconf2DEFS_H_
#define __wrappedgconf2DEFS_H_
#endif // __wrappedgconf2DEFS_H_
@@ -0,0 +1,17 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgconf2TYPES_H_
#define __wrappedgconf2TYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
#define SUPER() ADDED_FUNCTIONS()
#endif // __wrappedgconf2TYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgconf2UNDEFS_H_
#define __wrappedgconf2UNDEFS_H_
#endif // __wrappedgconf2UNDEFS_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgdkpixbuf2DEFS_H_
#define __wrappedgdkpixbuf2DEFS_H_
#endif // __wrappedgdkpixbuf2DEFS_H_
@@ -0,0 +1,19 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgdkpixbuf2TYPES_H_
#define __wrappedgdkpixbuf2TYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
typedef void* (*pFpiiiiiipp_t)(void*, int64_t, int64_t, int64_t, int64_t, int64_t, int64_t, void*, void*);
#define SUPER() ADDED_FUNCTIONS() \
GO(gdk_pixbuf_new_from_data, pFpiiiiiipp_t)
#endif // __wrappedgdkpixbuf2TYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgdkpixbuf2UNDEFS_H_
#define __wrappedgdkpixbuf2UNDEFS_H_
#endif // __wrappedgdkpixbuf2UNDEFS_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgdkx112DEFS_H_
#define __wrappedgdkx112DEFS_H_
#endif // __wrappedgdkx112DEFS_H_
@@ -0,0 +1,29 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgdkx112TYPES_H_
#define __wrappedgdkx112TYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
typedef void (*vFpp_t)(void*, void*);
typedef int64_t (*iFpp_t)(void*, void*);
typedef void (*vFppp_t)(void*, void*, void*);
typedef int64_t (*iFiipp_t)(int64_t, int64_t, void*, void*);
typedef int64_t (*iFiippp_t)(int64_t, int64_t, void*, void*, void*);
#define SUPER() ADDED_FUNCTIONS() \
GO(gdk_init, vFpp_t) \
GO(gdk_init_check, iFpp_t) \
GO(gdk_event_handler_set, vFppp_t) \
GO(gdk_window_add_filter, vFppp_t) \
GO(gdk_window_remove_filter, vFppp_t) \
GO(gdk_input_add, iFiipp_t) \
GO(gdk_input_add_full, iFiippp_t)
#endif // __wrappedgdkx112TYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgdkx112UNDEFS_H_
#define __wrappedgdkx112UNDEFS_H_
#endif // __wrappedgdkx112UNDEFS_H_
+8
View File
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgio2DEFS_H_
#define __wrappedgio2DEFS_H_
#endif // __wrappedgio2DEFS_H_
+81
View File
@@ -0,0 +1,81 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgio2TYPES_H_
#define __wrappedgio2TYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
typedef void (*vFppp_t)(void*, void*, void*);
typedef void (*vFippp_t)(int64_t, void*, void*, void*);
typedef void (*vFppip_t)(void*, void*, int64_t, void*);
typedef void (*vFpppp_t)(void*, void*, void*, void*);
typedef uint64_t (*uFpppp_t)(void*, void*, void*, void*);
typedef uintptr_t (*LFpppp_t)(void*, void*, void*, void*);
typedef void* (*pFpppp_t)(void*, void*, void*, void*);
typedef void (*vFpippp_t)(void*, int64_t, void*, void*, void*);
typedef void (*vFppipV_t)(void*, void*, int64_t, void*, ...);
typedef void (*vFppipA_t)(void*, void*, int64_t, void*, va_list);
typedef void (*vFpipppp_t)(void*, int64_t, void*, void*, void*, void*);
typedef void (*vFiippppV_t)(int64_t, int64_t, void*, void*, void*, void*, ...);
typedef void (*vFiupippp_t)(int64_t, uint64_t, void*, int64_t, void*, void*, void*);
typedef void (*vFippippp_t)(int64_t, void*, void*, int64_t, void*, void*, void*);
typedef void (*vFppipppp_t)(void*, void*, int64_t, void*, void*, void*, void*);
typedef void (*vFpppuipV_t)(void*, void*, void*, uint64_t, int64_t, void*, ...);
typedef uint64_t (*uFipipppp_t)(int64_t, void*, int64_t, void*, void*, void*, void*);
typedef uint64_t (*uFppipppp_t)(void*, void*, int64_t, void*, void*, void*, void*);
typedef uint64_t (*uFppppppp_t)(void*, void*, void*, void*, void*, void*, void*);
typedef void* (*pFpppuipV_t)(void*, void*, void*, uint64_t, int64_t, void*, ...);
typedef void (*vFppiipppp_t)(void*, void*, int64_t, int64_t, void*, void*, void*, void*);
typedef void (*vFpppiippp_t)(void*, void*, void*, int64_t, int64_t, void*, void*, void*);
typedef uint64_t (*uFipippppp_t)(int64_t, void*, int64_t, void*, void*, void*, void*, void*);
typedef void (*vFiippppppp_t)(int64_t, int64_t, void*, void*, void*, void*, void*, void*, void*);
typedef void (*vFpippppppp_t)(void*, int64_t, void*, void*, void*, void*, void*, void*, void*);
typedef void (*vFpppiipppp_t)(void*, void*, void*, int64_t, int64_t, void*, void*, void*, void*);
typedef void* (*pFiippppppp_t)(int64_t, int64_t, void*, void*, void*, void*, void*, void*, void*);
typedef uint64_t (*uFppppppippp_t)(void*, void*, void*, void*, void*, void*, int64_t, void*, void*, void*);
typedef void (*vFpppppppiippp_t)(void*, void*, void*, void*, void*, void*, void*, int64_t, int64_t, void*, void*, void*);
#define SUPER() ADDED_FUNCTIONS() \
GO(g_simple_async_result_set_op_res_gpointer, vFppp_t) \
GO(g_bus_get, vFippp_t) \
GO(g_simple_async_result_run_in_thread, vFppip_t) \
GO(g_dbus_connection_close, vFpppp_t) \
GO(g_dbus_connection_flush, vFpppp_t) \
GO(g_simple_async_report_gerror_in_idle, vFpppp_t) \
GO(g_simple_async_report_take_gerror_in_idle, vFpppp_t) \
GO(g_dbus_connection_add_filter, uFpppp_t) \
GO(g_cancellable_connect, LFpppp_t) \
GO(g_simple_async_result_new, pFpppp_t) \
GO(g_simple_async_result_new_from_error, pFpppp_t) \
GO(g_simple_async_result_new_take_error, pFpppp_t) \
GO(g_async_initable_init_async, vFpippp_t) \
GO(g_simple_async_result_set_error, vFppipV_t) \
GO(g_simple_async_result_set_error_va, vFppipA_t) \
GO(g_dbus_connection_new_for_address, vFpipppp_t) \
GO(g_async_initable_new_async, vFiippppV_t) \
GO(g_async_initable_newv_async, vFiupippp_t) \
GO(g_async_initable_new_valist_async, vFippippp_t) \
GO(g_dbus_connection_new, vFppipppp_t) \
GO(g_simple_async_report_error_in_idle, vFpppuipV_t) \
GO(g_bus_watch_name, uFipipppp_t) \
GO(g_bus_own_name_on_connection, uFppipppp_t) \
GO(g_bus_watch_name_on_connection, uFppipppp_t) \
GO(g_dbus_connection_register_object, uFppppppp_t) \
GO(g_simple_async_result_new_error, pFpppuipV_t) \
GO(g_dbus_connection_send_message_with_reply, vFppiipppp_t) \
GO(g_dbus_proxy_call, vFpppiippp_t) \
GO(g_bus_own_name, uFipippppp_t) \
GO(g_dbus_proxy_new_for_bus, vFiippppppp_t) \
GO(g_dbus_proxy_new, vFpippppppp_t) \
GO(g_dbus_proxy_call_with_unix_fd_list, vFpppiipppp_t) \
GO(g_dbus_object_manager_client_new_for_bus_sync, pFiippppppp_t) \
GO(g_dbus_connection_signal_subscribe, uFppppppippp_t) \
GO(g_dbus_connection_call, vFpppppppiippp_t)
#endif // __wrappedgio2TYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgio2UNDEFS_H_
#define __wrappedgio2UNDEFS_H_
#endif // __wrappedgio2UNDEFS_H_
+8
View File
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedglib2DEFS_H_
#define __wrappedglib2DEFS_H_
#endif // __wrappedglib2DEFS_H_
+158
View File
@@ -0,0 +1,158 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedglib2TYPES_H_
#define __wrappedglib2TYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
typedef void (*vFp_t)(void*);
typedef void* (*pFp_t)(void*);
typedef void (*vFpp_t)(void*, void*);
typedef void (*vFpV_t)(void*, ...);
typedef int64_t (*iFpp_t)(void*, void*);
typedef int64_t (*iFpV_t)(void*, ...);
typedef uint64_t (*uFpp_t)(void*, void*);
typedef void* (*pFup_t)(uint64_t, void*);
typedef void* (*pFpu_t)(void*, uint64_t);
typedef void* (*pFpp_t)(void*, void*);
typedef void* (*pFpV_t)(void*, ...);
typedef void* (*pFpA_t)(void*, va_list);
typedef void (*vFppp_t)(void*, void*, void*);
typedef void (*vFppV_t)(void*, void*, ...);
typedef void (*vFppA_t)(void*, void*, va_list);
typedef int64_t (*iFppp_t)(void*, void*, void*);
typedef int64_t (*iFppV_t)(void*, void*, ...);
typedef uint64_t (*uFipp_t)(int64_t, void*, void*);
typedef uint64_t (*uFupp_t)(uint64_t, void*, void*);
typedef uint64_t (*uFppp_t)(void*, void*, void*);
typedef void* (*pFppp_t)(void*, void*, void*);
typedef void* (*pFppV_t)(void*, void*, ...);
typedef void (*vFpipV_t)(void*, int64_t, void*, ...);
typedef void (*vFpipA_t)(void*, int64_t, void*, va_list);
typedef void (*vFpupp_t)(void*, uint64_t, void*, void*);
typedef void (*vFpppp_t)(void*, void*, void*, void*);
typedef int64_t (*iFpLpp_t)(void*, uintptr_t, void*, void*);
typedef int64_t (*iFpLpV_t)(void*, uintptr_t, void*, ...);
typedef uint64_t (*uFippp_t)(int64_t, void*, void*, void*);
typedef uint64_t (*uFpipp_t)(void*, int64_t, void*, void*);
typedef void* (*pFpipV_t)(void*, int64_t, void*, ...);
typedef void* (*pFpipA_t)(void*, int64_t, void*, va_list);
typedef void* (*pFpupp_t)(void*, uint64_t, void*, void*);
typedef void* (*pFppip_t)(void*, void*, int64_t, void*);
typedef void* (*pFpppp_t)(void*, void*, void*, void*);
typedef void (*vFpiLpp_t)(void*, int64_t, uintptr_t, void*, void*);
typedef void (*vFppipV_t)(void*, void*, int64_t, void*, ...);
typedef uint64_t (*uFiippp_t)(int64_t, int64_t, void*, void*, void*);
typedef uint64_t (*uFiuppp_t)(int64_t, uint64_t, void*, void*, void*);
typedef int64_t (*iFpupppp_t)(void*, uint64_t, void*, void*, void*, void*);
typedef uint64_t (*uFpiippp_t)(void*, int64_t, int64_t, void*, void*, void*);
typedef void* (*pFppuipp_t)(void*, void*, uint64_t, int64_t, void*, void*);
typedef void* (*pFppLiiip_t)(void*, void*, uintptr_t, int64_t, int64_t, int64_t, void*);
typedef int64_t (*iFpppipppp_t)(void*, void*, void*, int64_t, void*, void*, void*, void*);
typedef int64_t (*iFpppipppppp_t)(void*, void*, void*, int64_t, void*, void*, void*, void*, void*, void*);
typedef int64_t (*iFpppippppppp_t)(void*, void*, void*, int64_t, void*, void*, void*, void*, void*, void*, void*);
#define SUPER() ADDED_FUNCTIONS() \
GO(g_atexit, vFp_t) \
GO(g_completion_new, pFp_t) \
GO(g_main_context_get_poll_func, pFp_t) \
GO(g_private_new, pFp_t) \
GO(g_ptr_array_new_with_free_func, pFp_t) \
GO(g_set_print_handler, pFp_t) \
GO(g_set_printerr_handler, pFp_t) \
GO(g_array_set_clear_func, vFpp_t) \
GO(g_array_sort, vFpp_t) \
GO(g_completion_set_compare, vFpp_t) \
GO(g_list_free_full, vFpp_t) \
GO(g_main_context_set_poll_func, vFpp_t) \
GO(g_ptr_array_set_free_func, vFpp_t) \
GO(g_ptr_array_sort, vFpp_t) \
GO(g_source_set_funcs, vFpp_t) \
GO(g_thread_foreach, vFpp_t) \
GO(g_print, vFpV_t) \
GO(g_printerr, vFpV_t) \
GO(g_source_remove_by_funcs_user_data, iFpp_t) \
GO(g_vprintf, iFpp_t) \
GO(g_printf, iFpV_t) \
GO(g_idle_add, uFpp_t) \
GO(g_printf_string_upper_bound, uFpp_t) \
GO(g_ptr_array_new_full, pFup_t) \
GO(g_source_new, pFpu_t) \
GO(g_hash_table_new, pFpp_t) \
GO(g_list_sort, pFpp_t) \
GO(g_log_set_default_handler, pFpp_t) \
GO(g_slist_sort, pFpp_t) \
GO(g_strdup_vprintf, pFpp_t) \
GO(g_build_filename, pFpV_t) \
GO(g_markup_printf_escaped, pFpV_t) \
GO(g_strdup_printf, pFpV_t) \
GO(g_strjoin, pFpV_t) \
GO(g_variant_new, pFpV_t) \
GO(g_markup_vprintf_escaped, pFpA_t) \
GO(g_strjoinv, pFpA_t) \
GO(g_variant_new_parsed_va, pFpA_t) \
GO(g_array_sort_with_data, vFppp_t) \
GO(g_hash_table_foreach, vFppp_t) \
GO(g_ptr_array_foreach, vFppp_t) \
GO(g_ptr_array_sort_with_data, vFppp_t) \
GO(g_static_private_set, vFppp_t) \
GO(g_string_append_printf, vFppV_t) \
GO(g_string_printf, vFppV_t) \
GO(g_variant_get, vFppV_t) \
GO(g_string_append_vprintf, vFppA_t) \
GO(g_string_vprintf, vFppA_t) \
GO(g_vasprintf, iFppp_t) \
GO(g_vfprintf, iFppp_t) \
GO(g_vsprintf, iFppp_t) \
GO(g_fprintf, iFppV_t) \
GO(g_sprintf, iFppV_t) \
GO(g_child_watch_add, uFipp_t) \
GO(g_timeout_add, uFupp_t) \
GO(g_timeout_add_seconds, uFupp_t) \
GO(g_hash_table_foreach_remove, uFppp_t) \
GO(g_hash_table_foreach_steal, uFppp_t) \
GO(g_hash_table_find, pFppp_t) \
GO(g_list_find_custom, pFppp_t) \
GO(g_list_sort_with_data, pFppp_t) \
GO(g_queue_find_custom, pFppp_t) \
GO(g_slist_find_custom, pFppp_t) \
GO(g_slist_foreach, pFppp_t) \
GO(g_slist_insert_sorted, pFppp_t) \
GO(g_slist_sort_with_data, pFppp_t) \
GO(g_variant_new_va, pFppp_t) \
GO(g_build_path, pFppV_t) \
GO(g_log, vFpipV_t) \
GO(g_logv, vFpipA_t) \
GO(g_datalist_id_set_data_full, vFpupp_t) \
GO(g_source_set_callback, vFpppp_t) \
GO(g_vsnprintf, iFpLpp_t) \
GO(g_snprintf, iFpLpV_t) \
GO(g_idle_add_full, uFippp_t) \
GO(g_io_add_watch, uFpipp_t) \
GO(g_log_set_handler, uFpipp_t) \
GO(g_error_new, pFpipV_t) \
GO(g_error_new_valist, pFpipA_t) \
GO(g_datalist_id_dup_data, pFpupp_t) \
GO(g_thread_create, pFppip_t) \
GO(g_hash_table_new_full, pFpppp_t) \
GO(g_slist_insert_sorted_with_data, pFpppp_t) \
GO(g_qsort_with_data, vFpiLpp_t) \
GO(g_set_error, vFppipV_t) \
GO(g_child_watch_add_full, uFiippp_t) \
GO(g_timeout_add_full, uFiuppp_t) \
GO(g_timeout_add_seconds_full, uFiuppp_t) \
GO(g_datalist_id_replace_data, iFpupppp_t) \
GO(g_io_add_watch_full, uFpiippp_t) \
GO(g_variant_new_from_data, pFppuipp_t) \
GO(g_thread_create_full, pFppLiiip_t) \
GO(g_spawn_async, iFpppipppp_t) \
GO(g_spawn_sync, iFpppipppppp_t) \
GO(g_spawn_async_with_pipes, iFpppippppppp_t)
#endif // __wrappedglib2TYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedglib2UNDEFS_H_
#define __wrappedglib2UNDEFS_H_
#endif // __wrappedglib2UNDEFS_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgmodule2DEFS_H_
#define __wrappedgmodule2DEFS_H_
#endif // __wrappedgmodule2DEFS_H_
@@ -0,0 +1,17 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgmodule2TYPES_H_
#define __wrappedgmodule2TYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
#define SUPER() ADDED_FUNCTIONS()
#endif // __wrappedgmodule2TYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgmodule2UNDEFS_H_
#define __wrappedgmodule2UNDEFS_H_
#endif // __wrappedgmodule2UNDEFS_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgobject2DEFS_H_
#define __wrappedgobject2DEFS_H_
#endif // __wrappedgobject2DEFS_H_
@@ -0,0 +1,75 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgobject2TYPES_H_
#define __wrappedgobject2TYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
typedef void* (*pFp_t)(void*);
typedef int64_t (*iFpp_t)(void*, void*);
typedef void* (*pFpp_t)(void*, void*);
typedef void (*vFiip_t)(int64_t, int64_t, void*);
typedef void (*vFLLp_t)(uintptr_t, uintptr_t, void*);
typedef void (*vFppV_t)(void*, void*, ...);
typedef void (*vFppA_t)(void*, void*, va_list);
typedef uintptr_t (*LFppp_t)(void*, void*, void*);
typedef void* (*pFLpV_t)(uintptr_t, void*, ...);
typedef void* (*pFLpA_t)(uintptr_t, void*, va_list);
typedef void* (*pFppp_t)(void*, void*, void*);
typedef void* (*pFppV_t)(void*, void*, ...);
typedef void (*vFpuuV_t)(void*, uint64_t, uint64_t, ...);
typedef void (*vFpupp_t)(void*, uint64_t, void*, void*);
typedef void (*vFpupA_t)(void*, uint64_t, void*, va_list);
typedef void (*vFpppp_t)(void*, void*, void*, void*);
typedef uintptr_t (*LFLppi_t)(uintptr_t, void*, void*, int64_t);
typedef uintptr_t (*LFupppp_t)(uint64_t, void*, void*, void*, void*);
typedef uintptr_t (*LFLpppi_t)(uintptr_t, void*, void*, void*, int64_t);
typedef uintptr_t (*LFppppi_t)(void*, void*, void*, void*, int64_t);
typedef uintptr_t (*LFpppppu_t)(void*, void*, void*, void*, void*, uint64_t);
typedef uint64_t (*uFpiupppp_t)(void*, int64_t, uint64_t, void*, void*, void*, void*);
typedef uintptr_t (*LFLpLpLpi_t)(uintptr_t, void*, uintptr_t, void*, uintptr_t, void*, int64_t);
typedef uintptr_t (*LFpiupppp_t)(void*, int64_t, uint64_t, void*, void*, void*, void*);
typedef uint64_t (*uFpLiupppLuV_t)(void*, uintptr_t, int64_t, uint64_t, void*, void*, void*, uintptr_t, uint64_t, ...);
typedef uint64_t (*uFpLippppLup_t)(void*, uintptr_t, int64_t, void*, void*, void*, void*, uintptr_t, uint64_t, void*);
typedef uint64_t (*uFpLippppLuA_t)(void*, uintptr_t, int64_t, void*, void*, void*, void*, uintptr_t, uint64_t, va_list);
#define SUPER() ADDED_FUNCTIONS() \
GO(g_type_class_peek_parent, pFp_t) \
GO(g_param_type_register_static, iFpp_t) \
GO(g_value_array_sort, pFpp_t) \
GO(g_value_register_transform_func, vFiip_t) \
GO(g_type_add_interface_static, vFLLp_t) \
GO(g_object_get, vFppV_t) \
GO(g_object_set, vFppV_t) \
GO(g_object_get_valist, vFppA_t) \
GO(g_object_set_valist, vFppA_t) \
GO(g_boxed_type_register_static, LFppp_t) \
GO(g_object_new, pFLpV_t) \
GO(g_object_new_valist, pFLpA_t) \
GO(g_value_array_sort_with_data, pFppp_t) \
GO(g_object_connect, pFppV_t) \
GO(g_signal_emit, vFpuuV_t) \
GO(g_param_spec_set_qdata_full, vFpupp_t) \
GO(g_signal_emit_valist, vFpupA_t) \
GO(g_object_set_data_full, vFpppp_t) \
GO(g_type_register_static, LFLppi_t) \
GO(g_signal_add_emission_hook, LFupppp_t) \
GO(g_type_register_fundamental, LFLpppi_t) \
GO(g_signal_connect_object, LFppppi_t) \
GO(g_signal_connect_data, LFpppppu_t) \
GO(g_signal_handlers_block_matched, uFpiupppp_t) \
GO(g_signal_handlers_disconnect_matched, uFpiupppp_t) \
GO(g_signal_handlers_unblock_matched, uFpiupppp_t) \
GO(g_type_register_static_simple, LFLpLpLpi_t) \
GO(g_signal_handler_find, LFpiupppp_t) \
GO(g_signal_new, uFpLiupppLuV_t) \
GO(g_signal_newv, uFpLippppLup_t) \
GO(g_signal_new_valist, uFpLippppLuA_t)
#endif // __wrappedgobject2TYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgobject2UNDEFS_H_
#define __wrappedgobject2UNDEFS_H_
#endif // __wrappedgobject2UNDEFS_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgthread2DEFS_H_
#define __wrappedgthread2DEFS_H_
#endif // __wrappedgthread2DEFS_H_
@@ -0,0 +1,20 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgthread2TYPES_H_
#define __wrappedgthread2TYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
typedef void (*vFp_t)(void*);
#define SUPER() ADDED_FUNCTIONS() \
GO(g_thread_init, vFp_t) \
GO(g_thread_init_with_errorcheck_mutexes, vFp_t)
#endif // __wrappedgthread2TYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgthread2UNDEFS_H_
#define __wrappedgthread2UNDEFS_H_
#endif // __wrappedgthread2UNDEFS_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgtkx112DEFS_H_
#define __wrappedgtkx112DEFS_H_
#endif // __wrappedgtkx112DEFS_H_
@@ -0,0 +1,98 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgtkx112TYPES_H_
#define __wrappedgtkx112TYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
typedef float (*fFp_t)(void*);
typedef void* (*pFi_t)(int64_t);
typedef void (*vFpp_t)(void*, void*);
typedef int64_t (*iFpp_t)(void*, void*);
typedef void* (*pFiV_t)(int64_t, ...);
typedef void* (*pFpi_t)(void*, int64_t);
typedef void (*vFppp_t)(void*, void*, void*);
typedef void (*vFppV_t)(void*, void*, ...);
typedef void (*vFppA_t)(void*, void*, va_list);
typedef uint64_t (*uFupp_t)(uint64_t, void*, void*);
typedef void (*vFppiV_t)(void*, void*, int64_t, ...);
typedef void (*vFppup_t)(void*, void*, uint64_t, void*);
typedef void (*vFpppp_t)(void*, void*, void*, void*);
typedef int64_t (*iFpppp_t)(void*, void*, void*, void*);
typedef uintptr_t (*LFpppp_t)(void*, void*, void*, void*);
typedef void (*vFpippp_t)(void*, int64_t, void*, void*, void*);
typedef void (*vFppupp_t)(void*, void*, uint64_t, void*, void*);
typedef void (*vFppppp_t)(void*, void*, void*, void*, void*);
typedef void (*vFpuipuV_t)(void*, uint64_t, int64_t, void*, uint64_t, ...);
typedef int64_t (*iFppuppp_t)(void*, void*, uint64_t, void*, void*, void*);
typedef int64_t (*iFpppppp_t)(void*, void*, void*, void*, void*, void*);
typedef uint64_t (*uFiipppp_t)(int64_t, int64_t, void*, void*, void*, void*);
typedef void (*vFpppppuu_t)(void*, void*, void*, void*, void*, uint64_t, uint64_t);
typedef void* (*pFppppppi_t)(void*, void*, void*, void*, void*, void*, int64_t);
typedef void* (*pFppppppp_t)(void*, void*, void*, void*, void*, void*, void*);
typedef uintptr_t (*LFppppppii_t)(void*, void*, void*, void*, void*, void*, int64_t, int64_t);
typedef void* (*pFpppppppi_t)(void*, void*, void*, void*, void*, void*, void*, int64_t);
typedef void* (*pFpippppppp_t)(void*, int64_t, void*, void*, void*, void*, void*, void*, void*);
typedef void* (*pFpipppppppi_t)(void*, int64_t, void*, void*, void*, void*, void*, void*, void*, int64_t);
#define SUPER() ADDED_FUNCTIONS() \
GO(gtk_spin_button_get_value_as_float, fFp_t) \
GO(gtk_type_class, pFi_t) \
GO(gtk_builder_connect_signals, vFpp_t) \
GO(gtk_init, vFpp_t) \
GO(gtk_init_check, iFpp_t) \
GO(gtk_type_unique, iFpp_t) \
GO(gtk_list_store_new, pFiV_t) \
GO(gtk_tree_store_new, pFiV_t) \
GO(gtk_type_check_object_cast, pFpi_t) \
GO(gtk_builder_connect_signals_full, vFppp_t) \
GO(gtk_clipboard_request_text, vFppp_t) \
GO(gtk_container_forall, vFppp_t) \
GO(gtk_container_foreach, vFppp_t) \
GO(gtk_menu_attach_to_widget, vFppp_t) \
GO(gtk_tree_model_foreach, vFppp_t) \
GO(gtk_dialog_add_buttons, vFppV_t) \
GO(gtk_list_store_set, vFppV_t) \
GO(gtk_message_dialog_format_secondary_markup, vFppV_t) \
GO(gtk_message_dialog_format_secondary_text, vFppV_t) \
GO(gtk_tree_model_get, vFppV_t) \
GO(gtk_widget_style_get, vFppV_t) \
GO(gtk_list_store_set_valist, vFppA_t) \
GO(gtk_tree_model_get_valist, vFppA_t) \
GO(gtk_widget_style_get_valist, vFppA_t) \
GO(gtk_timeout_add, uFupp_t) \
GO(gtk_list_store_insert_with_values, vFppiV_t) \
GO(gtk_action_group_add_actions, vFppup_t) \
GO(gtk_clipboard_request_contents, vFpppp_t) \
GO(gtk_object_set_data_full, vFpppp_t) \
GO(gtk_stock_set_translate_func, vFpppp_t) \
GO(gtk_tree_sortable_set_default_sort_func, vFpppp_t) \
GO(gtk_tree_view_set_search_equal_func, vFpppp_t) \
GO(gtk_text_iter_backward_find_char, iFpppp_t) \
GO(gtk_text_iter_forward_find_char, iFpppp_t) \
GO(gtk_signal_connect, LFpppp_t) \
GO(gtk_tree_sortable_set_sort_func, vFpippp_t) \
GO(gtk_action_group_add_actions_full, vFppupp_t) \
GO(gtk_cell_layout_set_cell_data_func, vFppppp_t) \
GO(gtk_binding_entry_add_signal, vFpuipuV_t) \
GO(gtk_clipboard_set_with_data, iFppuppp_t) \
GO(gtk_clipboard_set_with_owner, iFppuppp_t) \
GO(gtk_init_with_args, iFpppppp_t) \
GO(gtk_input_add_full, uFiipppp_t) \
GO(gtk_menu_popup, vFpppppuu_t) \
GO(gtk_toolbar_insert_stock, pFppppppi_t) \
GO(gtk_toolbar_append_item, pFppppppp_t) \
GO(gtk_toolbar_prepend_item, pFppppppp_t) \
GO(gtk_signal_connect_full, LFppppppii_t) \
GO(gtk_toolbar_insert_item, pFpppppppi_t) \
GO(gtk_toolbar_append_element, pFpippppppp_t) \
GO(gtk_toolbar_prepend_element, pFpippppppp_t) \
GO(gtk_toolbar_insert_element, pFpipppppppi_t)
#endif // __wrappedgtkx112TYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedgtkx112UNDEFS_H_
#define __wrappedgtkx112UNDEFS_H_
#endif // __wrappedgtkx112UNDEFS_H_
+1
View File
@@ -92,6 +92,7 @@ typedef int64_t (*iFpippppp_t)(void*, int64_t, void*, void*, void*, void*, void*
GO(getauxval, LFL_t) \
GO(malloc, pFL_t) \
GO(__deregister_frame_info, pFp_t) \
GO(mallinfo, pFp_t) \
GO(__longjmp_chk, vFpi_t) \
GO(_longjmp, vFpi_t) \
GO(longjmp, vFpi_t) \
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedlibncursesw6DEFS_H_
#define __wrappedlibncursesw6DEFS_H_
#endif // __wrappedlibncursesw6DEFS_H_
@@ -0,0 +1,27 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedlibncursesw6TYPES_H_
#define __wrappedlibncursesw6TYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
typedef void* (*pFv_t)(void);
typedef int64_t (*iFpV_t)(void*, ...);
typedef int64_t (*iFppA_t)(void*, void*, va_list);
typedef int64_t (*iFiipV_t)(int64_t, int64_t, void*, ...);
typedef int64_t (*iFpiipV_t)(void*, int64_t, int64_t, void*, ...);
#define SUPER() ADDED_FUNCTIONS() \
GO(initscr, pFv_t) \
GO(printw, iFpV_t) \
GO(vwprintw, iFppA_t) \
GO(mvprintw, iFiipV_t) \
GO(mvwprintw, iFpiipV_t)
#endif // __wrappedlibncursesw6TYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedlibncursesw6UNDEFS_H_
#define __wrappedlibncursesw6UNDEFS_H_
#endif // __wrappedlibncursesw6UNDEFS_H_
@@ -14,6 +14,7 @@
typedef void (*vFp_t)(void*);
typedef int64_t (*iFp_t)(void*);
typedef void (*vFpi_t)(void*, int64_t);
typedef int64_t (*iFLp_t)(uintptr_t, void*);
typedef int64_t (*iFpi_t)(void*, int64_t);
typedef int64_t (*iFpL_t)(void*, uintptr_t);
typedef int64_t (*iFpp_t)(void*, void*);
@@ -48,6 +49,7 @@ typedef int64_t (*iFpppp_t)(void*, void*, void*, void*);
GO(pthread_mutexattr_init, iFp_t) \
GO(_pthread_cleanup_pop, vFpi_t) \
GO(_pthread_cleanup_pop_restore, vFpi_t) \
GO(pthread_getattr_np, iFLp_t) \
GO(__pthread_mutexattr_settype, iFpi_t) \
GO(pthread_attr_setdetachstate, iFpi_t) \
GO(pthread_attr_setinheritsched, iFpi_t) \
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedlibsndfileDEFS_H_
#define __wrappedlibsndfileDEFS_H_
#endif // __wrappedlibsndfileDEFS_H_
@@ -0,0 +1,21 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedlibsndfileTYPES_H_
#define __wrappedlibsndfileTYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
typedef int64_t (*iFp_t)(void*);
typedef void* (*pFpipp_t)(void*, int64_t, void*, void*);
#define SUPER() ADDED_FUNCTIONS() \
GO(sf_close, iFp_t) \
GO(sf_open_virtual, pFpipp_t)
#endif // __wrappedlibsndfileTYPES_H_
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappedlibsndfileUNDEFS_H_
#define __wrappedlibsndfileUNDEFS_H_
#endif // __wrappedlibsndfileUNDEFS_H_
+2
View File
@@ -12,6 +12,7 @@
#endif
typedef int64_t (*iFp_t)(void*);
typedef int64_t (*iFpi_t)(void*, int64_t);
typedef int64_t (*iFppi_t)(void*, void*, int64_t);
typedef int64_t (*iFpipi_t)(void*, int64_t, void*, int64_t);
typedef int64_t (*iFpippi_t)(void*, int64_t, void*, void*, int64_t);
@@ -20,6 +21,7 @@ typedef int64_t (*iFpiiiiipi_t)(void*, int64_t, int64_t, int64_t, int64_t, int64
#define SUPER() ADDED_FUNCTIONS() \
GO(deflateEnd, iFp_t) \
GO(inflateEnd, iFp_t) \
GO(inflate, iFpi_t) \
GO(inflateInit_, iFppi_t) \
GO(deflateInit_, iFpipi_t) \
GO(inflateInit2_, iFpipi_t) \
+8
View File
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappednslDEFS_H_
#define __wrappednslDEFS_H_
#endif // __wrappednslDEFS_H_
+17
View File
@@ -0,0 +1,17 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappednslTYPES_H_
#define __wrappednslTYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
#define SUPER() ADDED_FUNCTIONS()
#endif // __wrappednslTYPES_H_
+8
View File
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappednslUNDEFS_H_
#define __wrappednslUNDEFS_H_
#endif // __wrappednslUNDEFS_H_
+8
View File
@@ -0,0 +1,8 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappednspr4DEFS_H_
#define __wrappednspr4DEFS_H_
#endif // __wrappednspr4DEFS_H_
+17
View File
@@ -0,0 +1,17 @@
/*******************************************************************
* File automatically generated by rebuild_wrappers.py (v2.1.0.16) *
*******************************************************************/
#ifndef __wrappednspr4TYPES_H_
#define __wrappednspr4TYPES_H_
#ifndef LIBNAME
#error You should only #include this file inside a wrapped*.c file
#endif
#ifndef ADDED_FUNCTIONS
#define ADDED_FUNCTIONS()
#endif
#define SUPER() ADDED_FUNCTIONS()
#endif // __wrappednspr4TYPES_H_
Loaded 100 of 191 files, more files were not shown because too many files have changed in this diff. Show more