Files
AnyPS5/core/libs/tests/AvPlayerHttpModules.cmake
T

200 lines
8.4 KiB
CMake

cmake_policy(SET CMP0054 NEW)
set(positional)
set(afterSeparator FALSE)
math(EXPR lastArgument "${CMAKE_ARGC} - 1")
foreach(index RANGE 0 ${lastArgument})
if(afterSeparator)
list(APPEND positional "${CMAKE_ARGV${index}}")
elseif("${CMAKE_ARGV${index}}" STREQUAL "--")
set(afterSeparator TRUE)
endif()
endforeach()
list(LENGTH positional positionalCount)
if(NOT positionalCount EQUAL 3)
message(FATAL_ERROR "Expected owner, HTTP client and AvPlayer test executables after --")
endif()
list(GET positional 0 OWNER_TEST)
list(GET positional 1 CLIENT_TEST)
list(GET positional 2 PLAYER_TEST)
foreach(required PYTHON SERVER PATCHER OWNER_TEST CLIENT_TEST PLAYER_TEST LIBC KERNEL INTERNAL HTTP AVPLAYER NATIVE OBJDUMP WORK_DIR)
if(NOT DEFINED ${required} OR "${${required}}" STREQUAL "")
message(FATAL_ERROR "Missing ${required}")
endif()
endforeach()
set(httpNids Xa86mkDT770 FcAd67QjrVw T+Un3eukNLs mh7PrvIiVtk WN6ypk6qEnU T8if7aGBDYs 7EfcZqAehgI M3Qx8MdigHk)
string(RANDOM LENGTH 16 ALPHABET abcdef0123456789 stageId)
set(stage "${WORK_DIR}/run-${stageId}")
file(MAKE_DIRECTORY "${stage}")
execute_process(COMMAND "${PATCHER}" --write-export-list "${LIBC}" "${stage}/libc.exports"
RESULT_VARIABLE status OUTPUT_VARIABLE output ERROR_VARIABLE error)
if(NOT status STREQUAL "0")
message(FATAL_ERROR "Normal libc export listing failed: ${output}${error}")
endif()
message("${output}${error}")
set(moduleNames libc libkernel libSceLibcInternal libSceHttp libSceAvPlayer libSceAvPlayer.native)
set(moduleVariables LIBC KERNEL INTERNAL HTTP AVPLAYER NATIVE)
foreach(index RANGE 0 5)
list(GET moduleNames ${index} module)
list(GET moduleVariables ${index} variable)
file(COPY_FILE "${${variable}}" "${stage}/${module}.prx")
if(module STREQUAL "libc")
execute_process(COMMAND "${PATCHER}" "${module}" "${stage}/${module}.prx"
RESULT_VARIABLE status OUTPUT_VARIABLE output ERROR_VARIABLE error)
else()
execute_process(COMMAND "${PATCHER}" "${module}" --preserve-export-list "${stage}/libc.exports" "${stage}/${module}.prx"
RESULT_VARIABLE status OUTPUT_VARIABLE output ERROR_VARIABLE error)
endif()
if(NOT status STREQUAL "0")
message(FATAL_ERROR "Normal ${module} patching failed: ${output}${error}")
endif()
message("${output}${error}")
endforeach()
if(WIN32 AND DEFINED ALLOCATOR_DIRECTORY)
foreach(allocator mimalloc.dll mimalloc-redirect.dll)
file(COPY_FILE "${ALLOCATOR_DIRECTORY}/${allocator}" "${stage}/${allocator}")
endforeach()
execute_process(COMMAND "${IMPORT_FIRST}" "${stage}/mimalloc.dll" mimalloc-redirect.dll
RESULT_VARIABLE status OUTPUT_VARIABLE output ERROR_VARIABLE error)
if(NOT status STREQUAL "0")
message(FATAL_ERROR "Normal allocator import ordering failed: ${output}${error}")
endif()
message("${output}${error}")
endif()
function(read_module file prefix)
execute_process(COMMAND "${OBJDUMP}" -p "${file}"
RESULT_VARIABLE status OUTPUT_VARIABLE output ERROR_VARIABLE error)
if(NOT status STREQUAL "0")
message(FATAL_ERROR "Module import inspection failed: ${output}${error}")
endif()
set(${prefix}_header "${output}" PARENT_SCOPE)
if(WIN32)
string(FIND "${output}" "[Ordinal/Name Pointer] Table" exportsAt)
if(exportsAt EQUAL -1)
message(FATAL_ERROR "Missing PE export table in ${file}")
endif()
string(SUBSTRING "${output}" ${exportsAt} -1 exports)
set(${prefix}_exports "${exports}" PARENT_SCOPE)
else()
execute_process(COMMAND "${OBJDUMP}" -T "${file}"
RESULT_VARIABLE status OUTPUT_VARIABLE symbols ERROR_VARIABLE error)
if(NOT status STREQUAL "0")
message(FATAL_ERROR "Module symbol inspection failed: ${symbols}${error}")
endif()
set(${prefix}_symbols "${symbols}" PARENT_SCOPE)
endif()
endfunction()
read_module("${stage}/libSceHttp.prx" http)
foreach(module libSceAvPlayer libSceAvPlayer.native)
read_module("${stage}/${module}.prx" player)
if(WIN32)
set(httpImports)
set(inHttp FALSE)
string(REPLACE "\n" ";" importLines "${player_header}")
foreach(line IN LISTS importLines)
string(STRIP "${line}" line)
if(line MATCHES "^DLL Name: (.+)$")
if(CMAKE_MATCH_1 STREQUAL "libSceHttp.prx")
set(inHttp TRUE)
else()
set(inHttp FALSE)
endif()
elseif(line MATCHES "^The Export Tables")
set(inHttp FALSE)
elseif(inHttp)
string(APPEND httpImports "${line}\n")
endif()
endforeach()
foreach(nid IN LISTS httpNids)
string(FIND "${httpImports}" "${nid}" importAt)
string(FIND "${http_exports}" "${nid}" providerAt)
string(FIND "${player_exports}" "${nid}" playerAt)
if(importAt EQUAL -1 OR providerAt EQUAL -1 OR NOT playerAt EQUAL -1)
message(FATAL_ERROR "Incorrect patched HTTP import/provider ${nid} in ${module}")
endif()
endforeach()
else()
if(NOT player_header MATCHES "NEEDED[ \t]+libSceHttp\\.prx")
message(FATAL_ERROR "${module} has no dynamic libSceHttp dependency")
endif()
string(REPLACE "\n" ";" playerLines "${player_symbols}")
string(REPLACE "\n" ";" providerLines "${http_symbols}")
foreach(nid IN LISTS httpNids)
set(importFound FALSE)
set(providerFound FALSE)
foreach(line IN LISTS playerLines)
string(FIND "${line}" "${nid}" nameAt)
if(NOT nameAt EQUAL -1)
string(FIND "${line}" "*UND*" undefinedAt)
if(undefinedAt EQUAL -1)
message(FATAL_ERROR "HTTP helper ${nid} is defined in ${module}")
endif()
set(importFound TRUE)
endif()
endforeach()
foreach(line IN LISTS providerLines)
string(FIND "${line}" "${nid}" nameAt)
string(FIND "${line}" "*UND*" undefinedAt)
if(NOT nameAt EQUAL -1 AND undefinedAt EQUAL -1)
set(providerFound TRUE)
endif()
endforeach()
if(NOT importFound OR NOT providerFound)
message(FATAL_ERROR "Incorrect patched HTTP import/provider ${nid} in ${module}")
endif()
endforeach()
endif()
endforeach()
foreach(kind OWNER CLIENT PLAYER)
get_filename_component(name "${${kind}_TEST}" NAME)
file(COPY_FILE "${${kind}_TEST}" "${stage}/${name}")
set(${kind}_COPY "${stage}/${name}")
if(NOT kind STREQUAL "OWNER")
execute_process(COMMAND "${PATCHER}" --exec --only-sce "${stage}/${name}"
RESULT_VARIABLE status OUTPUT_VARIABLE output ERROR_VARIABLE error)
if(NOT status STREQUAL "0")
message(FATAL_ERROR "Test import patching failed: ${output}${error}")
endif()
endif()
endforeach()
if(WIN32)
set(libraryEnvironment "PATH=${stage};$ENV{PATH}")
else()
set(libraryEnvironment "LD_LIBRARY_PATH=${stage}:$ENV{LD_LIBRARY_PATH}")
endif()
foreach(module libSceAvPlayer libSceAvPlayer.native)
execute_process(COMMAND "${CMAKE_COMMAND}" -E env "${libraryEnvironment}"
"${OWNER_COPY}" "${stage}" "${module}.prx"
RESULT_VARIABLE status OUTPUT_VARIABLE output ERROR_VARIABLE error)
if(NOT status STREQUAL "0")
message(FATAL_ERROR "Patched module ownership failed: ${output}${error}")
endif()
message("${output}${error}")
endforeach()
file(MAKE_DIRECTORY "${stage}/client" "${stage}/player")
execute_process(COMMAND "${CMAKE_COMMAND}" -E env "${libraryEnvironment}"
"${PYTHON}" "${SERVER}" "${CLIENT_COPY}" client
WORKING_DIRECTORY "${stage}/client"
RESULT_VARIABLE status OUTPUT_VARIABLE output ERROR_VARIABLE error)
if(NOT status STREQUAL "0")
message(FATAL_ERROR "Patched HTTP client behavior failed: ${output}${error}")
endif()
message("${output}${error}")
execute_process(COMMAND "${CMAKE_COMMAND}" -E env "${libraryEnvironment}"
"${PYTHON}" "${SERVER}" "${PLAYER_COPY}"
WORKING_DIRECTORY "${stage}/player"
RESULT_VARIABLE status OUTPUT_VARIABLE output ERROR_VARIABLE error)
if(NOT status STREQUAL "0")
message(FATAL_ERROR "Patched AvPlayer HTTP behavior failed: ${output}${error}")
endif()
message("${output}${error}")
message(STATUS "Patched HTTP stage ${stage}")