Merge pull request #105 from SamG-Coder/codex/quake-native-imports
fix(relinker,libs): decode EMMS and add native string and thread APIs
This commit is contained in:
commit
cc41e847c8
|
|
@ -5,6 +5,8 @@ target_sources(libc PRIVATE
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/src/specifics/windows/CrashReport.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/specifics/linux/DlIteratePhdr.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Strings.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/AllocatingStrings.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/WideConversion.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/StringExtensions.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Math.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/Time.cpp
|
||||
|
|
|
|||
|
|
@ -0,0 +1,82 @@
|
|||
#include "prx/libc/include/ApplicationHeap.hpp"
|
||||
#include "prx/libc/include/General.hpp"
|
||||
#include <cerrno>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <string>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "prx/libc/include/WindowsFormatting.hpp"
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
|
||||
char* APS5_VABI strndup_nid_postfix(const char* source, std::size_t limit) {
|
||||
std::size_t length = 0;
|
||||
while (length < limit && source[length] != '\0') ++length;
|
||||
try {
|
||||
auto* result = static_cast<char*>(ApplicationHeapAllocate_nid_no_patch(length + 1));
|
||||
if (!result) { errno = 12; return nullptr; }
|
||||
std::memcpy(result, source, length);
|
||||
result[length] = '\0';
|
||||
return result;
|
||||
} catch (const std::bad_alloc&) {
|
||||
errno = 12;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int APS5_VABI asprintf_nid_postfix(char** destination, const char* format, ...) {
|
||||
if (!destination) { errno = 22; return -1; }
|
||||
*destination = nullptr;
|
||||
if (!format) { errno = 22; return -1; }
|
||||
#ifdef _WIN32
|
||||
__builtin_sysv_va_list args;
|
||||
__builtin_sysv_va_start(args, format);
|
||||
#else
|
||||
std::va_list args;
|
||||
va_start(args, format);
|
||||
#endif
|
||||
int result = -1;
|
||||
try {
|
||||
#ifdef _WIN32
|
||||
std::string text;
|
||||
const int count = LibcDetail::FormatWindows(nullptr, 0, format, args, &text);
|
||||
const char* source = text.c_str();
|
||||
#else
|
||||
char* text = nullptr;
|
||||
const int count = ::vasprintf(&text, format, args);
|
||||
std::unique_ptr<char, decltype(&std::free)> owner(text, std::free);
|
||||
const char* source = text;
|
||||
#endif
|
||||
if (count >= 0) {
|
||||
auto* output = static_cast<char*>(ApplicationHeapAllocate_nid_no_patch(static_cast<std::size_t>(count) + 1));
|
||||
if (output) {
|
||||
std::memcpy(output, source, static_cast<std::size_t>(count) + 1);
|
||||
*destination = output;
|
||||
result = count;
|
||||
} else errno = 12;
|
||||
}
|
||||
} catch (const std::bad_alloc&) {
|
||||
errno = 12;
|
||||
} catch (...) {
|
||||
#ifdef _WIN32
|
||||
__builtin_sysv_va_end(args);
|
||||
#else
|
||||
va_end(args);
|
||||
#endif
|
||||
throw;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
__builtin_sysv_va_end(args);
|
||||
#else
|
||||
va_end(args);
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#include "prx/libc/include/general/VabiMacros.hpp"
|
||||
#include <cerrno>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
extern "C" std::size_t APS5_VABI wcstombs_nid_postfix(char* destination, const std::uint16_t* source, std::size_t capacity) {
|
||||
std::size_t count = 0;
|
||||
while (!destination || count < capacity) {
|
||||
const auto value = source[count];
|
||||
if (value > 255) {
|
||||
errno = 86;
|
||||
return static_cast<std::size_t>(-1);
|
||||
}
|
||||
if (destination) destination[count] = static_cast<char>(value);
|
||||
if (value == 0) break;
|
||||
++count;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ add_library(libkernel SHARED EXCLUDE_FROM_ALL
|
|||
${CMAKE_CURRENT_SOURCE_DIR}/Pthread/src/Rwlock.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Pthread/src/Sem.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Pthread/Posix/Attr.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Pthread/Posix/Barrier.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Pthread/Posix/Cond.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Pthread/Posix/Mutex.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Pthread/Posix/Rwlock.cpp
|
||||
|
|
|
|||
|
|
@ -0,0 +1,61 @@
|
|||
#include "prx/libc/include/General.hpp"
|
||||
#include <condition_variable>
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
#include <new>
|
||||
|
||||
struct PthreadBarrierPrivate {
|
||||
std::mutex mutex;
|
||||
std::condition_variable changed;
|
||||
unsigned count;
|
||||
unsigned arrived = 0;
|
||||
unsigned active = 0;
|
||||
std::uint64_t generation = 0;
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
int APS5_VABI pthread_barrier_init_nid_postfix(PthreadBarrierPrivate** barrier, const void* attr, unsigned count) {
|
||||
if (!barrier || count == 0) return 22;
|
||||
if (attr) NotImplemented_nid_no_patch("pthread_barrier_init: non-default attributes");
|
||||
try {
|
||||
auto* value = new PthreadBarrierPrivate;
|
||||
value->count = count;
|
||||
*barrier = value;
|
||||
return 0;
|
||||
} catch (const std::bad_alloc&) {
|
||||
return 12;
|
||||
}
|
||||
}
|
||||
|
||||
int APS5_VABI pthread_barrier_wait_nid_postfix(PthreadBarrierPrivate** barrier) {
|
||||
if (!barrier || !*barrier) return 22;
|
||||
auto& value = **barrier;
|
||||
std::unique_lock lock(value.mutex);
|
||||
const auto generation = value.generation;
|
||||
++value.active;
|
||||
if (++value.arrived == value.count) {
|
||||
value.arrived = 0;
|
||||
++value.generation;
|
||||
value.changed.notify_all();
|
||||
--value.active;
|
||||
return -1;
|
||||
}
|
||||
value.changed.wait(lock, [&] { return value.generation != generation; });
|
||||
--value.active;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI pthread_barrier_destroy_nid_postfix(PthreadBarrierPrivate** barrier) {
|
||||
if (!barrier || !*barrier) return 22;
|
||||
auto* value = *barrier;
|
||||
{
|
||||
std::lock_guard lock(value->mutex);
|
||||
if (value->active != 0) return 16;
|
||||
}
|
||||
delete value;
|
||||
*barrier = nullptr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -57,6 +57,15 @@ Pthread APS5_VABI pthread_self_nid_postfix(void) {
|
|||
return scePthreadSelf();
|
||||
}
|
||||
|
||||
int APS5_VABI pthread_equal_nid_postfix(Pthread first, Pthread second) {
|
||||
return first == second;
|
||||
}
|
||||
|
||||
int APS5_VABI sched_yield_nid_postfix(void) {
|
||||
std::this_thread::yield();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int APS5_VABI pthread_setcancelstate_nid_postfix(int state, int* old_state) {
|
||||
return PosixThread::ToErrno(scePthreadSetcancelstate(state, old_state));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ inline constexpr std::uint8_t TwoByteModRmRangeFMin = 0x38;
|
|||
inline constexpr std::uint8_t TwoByteModRmRangeFMax = 0x3A;
|
||||
inline constexpr std::uint8_t TwoByteModRmRangeGMin = 0x54;
|
||||
inline constexpr std::uint8_t TwoByteModRmRangeGMax = 0x7F;
|
||||
inline constexpr std::uint8_t TwoByteEmms = 0x77;
|
||||
inline constexpr std::uint8_t TwoByteModRmRangeHMin = 0xD0;
|
||||
inline constexpr std::uint8_t TwoByteModRmRangeHMax = 0xFE;
|
||||
inline constexpr std::uint8_t TwoByteNopModRm = 0x1F;
|
||||
|
|
|
|||
|
|
@ -252,7 +252,7 @@ std::size_t X64InstructionDecoder::Decode(const std::uint8_t* data, std::size_t
|
|||
(opcode >= TwoByteModRmRangeCMin && opcode <= TwoByteModRmRangeCMax) ||
|
||||
(opcode >= TwoByteModRmRangeDMin && opcode <= TwoByteModRmRangeDMax) ||
|
||||
(opcode >= TwoByteModRmRangeEMin && opcode <= TwoByteModRmRangeEMax) ||
|
||||
(opcode >= TwoByteModRmRangeGMin && opcode <= TwoByteModRmRangeGMax) ||
|
||||
(opcode >= TwoByteModRmRangeGMin && opcode <= TwoByteModRmRangeGMax && opcode != TwoByteEmms) ||
|
||||
(opcode >= TwoByteModRmRangeHMin && opcode <= TwoByteModRmRangeHMax) ||
|
||||
(opcode >= TwoByteModRmRangeIMin && opcode <= TwoByteModRmRangeIMax) ||
|
||||
(opcode >= TwoBytePrefetchGrpMin && opcode <= TwoBytePrefetchGrpMax) ||
|
||||
|
|
|
|||
Loading…
Reference in New Issue