Merge pull request #3214 from fma-rc/fix/libs-bind-now
fix(libs): bind the system libraries eagerly on Linux
This commit is contained in:
commit
1690db9a24
|
|
@ -53,6 +53,9 @@ set(LIBS_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
|||
add_subdirectory(${LIBC_DIR} ${CMAKE_CURRENT_BINARY_DIR}/prx/libc)
|
||||
target_include_directories(libc PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
configure_windows_unwind(libc)
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
target_link_options(libc PRIVATE LINKER:-z,now)
|
||||
endif()
|
||||
|
||||
set(UNPATCHED_DIR ${CMAKE_CURRENT_BINARY_DIR}/libs/unpatched)
|
||||
set(PATCHED_DIR ${CMAKE_CURRENT_BINARY_DIR}/libs)
|
||||
|
|
@ -102,6 +105,9 @@ foreach(LIB_DIR ${LIBS_DIRS})
|
|||
else()
|
||||
target_link_libraries(${LIB_NAME} PRIVATE libkernel libc)
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
||||
target_link_options(${LIB_NAME} PRIVATE LINKER:-z,now)
|
||||
endif()
|
||||
if(WIN32 AND LIB_NAME STREQUAL "libSceNet")
|
||||
target_link_libraries(${LIB_NAME} PRIVATE ws2_32)
|
||||
target_compile_definitions(${LIB_NAME} PRIVATE _WIN32_WINNT=0x0602)
|
||||
|
|
|
|||
|
|
@ -81,6 +81,30 @@ void APS5_VABI CheckedEntry(std::uint64_t, std::uint64_t) {
|
|||
for (;;) sceFiberReturnToThread(0, &received);
|
||||
}
|
||||
|
||||
constexpr std::size_t SmallContextSize = 2048;
|
||||
constexpr unsigned char SmallGuardFill = 0xa5;
|
||||
alignas(16) std::array<unsigned char, 64 * 1024> g_smallArea;
|
||||
FiberStorage g_smallStorage;
|
||||
|
||||
void APS5_VABI SmallEntry(std::uint64_t, std::uint64_t) {
|
||||
std::uint64_t received = 0;
|
||||
for (;;) sceFiberReturnToThread(0, &received);
|
||||
}
|
||||
|
||||
void RunSmallContextFirst() {
|
||||
auto* small = reinterpret_cast<FiberObject*>(&g_smallStorage);
|
||||
auto* context = g_smallArea.data() + g_smallArea.size() - SmallContextSize;
|
||||
g_smallArea.fill(SmallGuardFill);
|
||||
Require(sceFiberReturnToThread(0, nullptr) == FiberErrorPermission, "return to thread outside a fiber");
|
||||
Require(_sceFiberInitializeImpl_nid_postfix(small, "small", SmallEntry, 0, context, SmallContextSize, nullptr, 0) == 0, "initialize small");
|
||||
Require(sceFiberRun_nid_postfix(small, 0, nullptr) == 0, "first fiber run of the process on a 2 KiB context");
|
||||
Require(sceFiberRun_nid_postfix(small, 0, nullptr) == 0, "resume on a 2 KiB context");
|
||||
Require(sceFiberFinalize(small) == 0, "finalize small");
|
||||
for (auto* byte = g_smallArea.data(); byte != context; ++byte) {
|
||||
Require(*byte == SmallGuardFill, "nothing is written below a 2 KiB context");
|
||||
}
|
||||
}
|
||||
|
||||
[[gnu::noinline]] std::int32_t RunFirst(std::uint64_t* returned) {
|
||||
g_threadFramePointer = reinterpret_cast<std::uint64_t>(__builtin_frame_address(0));
|
||||
const std::int32_t result = sceFiberRun_nid_postfix(g_first, 100, returned);
|
||||
|
|
@ -91,6 +115,7 @@ void APS5_VABI CheckedEntry(std::uint64_t, std::uint64_t) {
|
|||
}
|
||||
|
||||
int main() {
|
||||
RunSmallContextFirst();
|
||||
FiberObject* self = nullptr;
|
||||
Require(sceFiberGetSelf(&self) == FiberErrorPermission, "no fiber on the thread");
|
||||
Require(_sceFiberInitializeImpl_nid_postfix(g_first, "first", FirstEntry, 11, g_firstContext.data(), g_firstContext.size(), nullptr, 0) == 0, "initialize first");
|
||||
|
|
|
|||
Loading…
Reference in New Issue