mirror of
https://github.com/boykopovar/AnyPS5.git
synced 2026-10-28 00:35:47 +00:00
Merge pull request #9582 from UnhealthyKraken/fix/libkernel-variant-timedjoin
test(libkernel): cover sys and web timed join imports
This commit is contained in:
2 files changed
+95
No files matched your search
@@ -2036,6 +2036,15 @@ if(BUILD_TESTING)
|
||||
target_include_directories(guest_timed_join_tests PRIVATE ${LIBS_INCLUDE_DIR})
|
||||
target_link_libraries(guest_timed_join_tests PRIVATE libkernel libc ${CMAKE_DL_LIBS})
|
||||
configure_windows_unwind(guest_timed_join_tests)
|
||||
if(WIN32 AND Python3_Interpreter_FOUND)
|
||||
foreach(joinProvider IN ITEMS libkernel_sys libkernel_web)
|
||||
add_test(NAME guest_timed_join_import_${joinProvider} COMMAND ${Python3_EXECUTABLE}
|
||||
${LIBS_INCLUDE_DIR}/tests/test_windows_timed_join_imports.py $<TARGET_FILE:relinker> ${PATCHED_DIR}
|
||||
${joinProvider}.prx $<TARGET_FILE_DIR:guest_timed_join_tests>)
|
||||
set_tests_properties(guest_timed_join_import_${joinProvider} PROPERTIES TIMEOUT 25
|
||||
ENVIRONMENT_MODIFICATION "PATH=path_list_prepend:$<TARGET_FILE_DIR:guest_timed_join_tests>")
|
||||
endforeach()
|
||||
endif()
|
||||
foreach(joinMode IN ITEMS normal coarse)
|
||||
add_test(NAME guest_timed_join_${joinMode} COMMAND guest_timed_join_tests $<TARGET_FILE:libkernel>)
|
||||
set_tests_properties(guest_timed_join_${joinMode} PROPERTIES TIMEOUT 15)
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
import os
|
||||
import shutil
|
||||
import struct
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parents[2] / 'relinker' / 'relinker' / 'tests'))
|
||||
from guest_import_fixtures import executable, fixture_directory
|
||||
|
||||
|
||||
def call(code, slot):
|
||||
code.extend(b'\xff\x15' + struct.pack('<i', slot - (0x4000 + len(code) + 6)))
|
||||
|
||||
|
||||
def fixture(variant, label):
|
||||
image = executable(variant, 'PkS44IGrDkM#A#B', extra_symbols=('OxhIB8LB-PQ#A#B',))
|
||||
code = bytearray(b'\x48\x83\xec\x38')
|
||||
if label == 'join':
|
||||
code.extend(b'\x48\x8d\x3c\x24\x31\xf6')
|
||||
code.extend(b'\x48\x8d\x15' + struct.pack('<i', 0x4300 - (0x4000 + len(code) + 7)))
|
||||
code.extend(b'\x48\xb9' + struct.pack('<Q', 0x123456789abcdef))
|
||||
call(code, 0x4a28)
|
||||
code.extend(b'\x85\xc0\x0f\x85')
|
||||
create_failure = len(code)
|
||||
code.extend(bytes(4))
|
||||
code.extend(b'\x48\x8b\x3c\x24\x48\x8d\x74\x24\x08')
|
||||
code.extend(b'\x48\xb8' + struct.pack('<Q', 0x7fffffffffffffff))
|
||||
code.extend(b'\x48\x89\x44\x24\x10')
|
||||
code.extend(b'\x48\xc7\x44\x24\x18' + struct.pack('<I', 999999999))
|
||||
code.extend(b'\x48\x8d\x54\x24\x10')
|
||||
call(code, 0x4a20)
|
||||
code.extend(b'\x85\xc0\x0f\x85')
|
||||
join_failure = len(code)
|
||||
code.extend(bytes(4))
|
||||
code.extend(b'\x48\xba' + struct.pack('<Q', 0x123456789abcdef))
|
||||
code.extend(b'\x48\x39\x54\x24\x08\x0f\x85')
|
||||
value_failure = len(code)
|
||||
code.extend(bytes(4))
|
||||
code.extend(b'\x31\xc0\x48\x83\xc4\x38\xc3')
|
||||
failure = len(code)
|
||||
code.extend(b'\xb8\x63\x00\x00\x00\x48\x83\xc4\x38\xc3')
|
||||
for offset in (create_failure, join_failure, value_failure):
|
||||
struct.pack_into('<i', code, offset, failure - offset - 4)
|
||||
image[0x4300:0x4304] = b'\x48\x89\xf8\xc3'
|
||||
else:
|
||||
thread = 1 if label == 'invalid-deadline' else 0
|
||||
code.extend(b'\xbf' + struct.pack('<I', thread) + b'\x31\xf6\x31\xd2')
|
||||
if label != 'null-deadline':
|
||||
code.extend(b'\x48\xc7\x44\x24\x10' + struct.pack('<i', -1 if thread else 0))
|
||||
code.extend(b'\x48\xc7\x44\x24\x18\x00\x00\x00\x00')
|
||||
code.extend(b'\x48\x8d\x54\x24\x10')
|
||||
call(code, 0x4a20)
|
||||
code.extend(b'\x48\x83\xc4\x38\xc3')
|
||||
image[0x4000:0x4000 + len(code)] = code
|
||||
return image
|
||||
|
||||
|
||||
def main():
|
||||
assert os.name == 'nt'
|
||||
relinker, libraries = (Path(value).resolve() for value in sys.argv[1:3])
|
||||
variant = sys.argv[3]
|
||||
runtime = Path(sys.argv[4]).resolve()
|
||||
assert variant in ('libkernel_sys.prx', 'libkernel_web.prx')
|
||||
with fixture_directory('anyps5-timed-join-') as directory:
|
||||
work = Path(directory)
|
||||
(work / 'libs').mkdir()
|
||||
(work / 'prx').mkdir()
|
||||
for name in (variant, 'libkernel.prx', 'libc.prx'):
|
||||
shutil.copy2(libraries / name, work / 'libs' / name)
|
||||
for name in ('libgcc_s_seh-1.dll', 'libstdc++-6.dll', 'libwinpthread-1.dll'):
|
||||
shutil.copy2(runtime / name, work / 'libs' / name)
|
||||
for label, expected in (('null-deadline', 22), ('invalid-deadline', 22), ('null-thread', 22), ('join', 0)):
|
||||
source = work / 'input.elf'
|
||||
source.write_bytes(fixture(variant, label))
|
||||
output = work / (label + '.exe')
|
||||
result = subprocess.run([str(relinker), '--windows', str(source), str(output)],
|
||||
capture_output=True, text=True, timeout=10)
|
||||
assert result.returncode == 0, (variant, label, result.stderr)
|
||||
result = subprocess.run([str(output)], cwd=work, capture_output=True, text=True, timeout=10)
|
||||
assert result.returncode == expected, (variant, label, result.returncode, result.stderr)
|
||||
print(variant + ': scoped timed-join validation and shared thread lifecycle passed')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in new issue
Block a user