Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions core/libs/prx/libkernel/System/src/SystemConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,4 +247,39 @@ int APS5_VABI sceKernelGetSystemSwVersion_nid_postfix(SceKernelSystemSwVersion*
version->version = 0x01000000;
return 0;
}

int APS5_VABI sysctlnametomib_nid_postfix(const char* name, int* mib, std::size_t* size) {
struct KnownName {
const char* name;
int mib[3];
std::size_t length;
};
static constexpr KnownName known[] = {
{"hw.model", {6, 2}, 2},
{"hw.ncpu", {6, 3}, 2},
{"hw.physmem", {6, 5}, 2},
{"hw.realmem", {6, 12}, 2},
{"kern.arandom", {1, 37}, 2},
{"kern.proc.pathname", {1, 14, 12}, 3},
};
constexpr std::size_t MaximumPath = 1024;
if (name == nullptr || size == nullptr) throw std::invalid_argument(std::string(__func__) + ": null name or size");
const std::size_t nameLength = strnlen(name, MaximumPath);
if (nameLength == MaximumPath) {
*__error_nid_postfix() = 63;
return -1;
}
if (nameLength == 0 || std::strcmp(name, "machdep.cacheline_size") == 0) {
*__error_nid_postfix() = 2;
return -1;
}
for (const auto& entry : known) {
if (std::strcmp(name, entry.name) != 0) continue;
std::size_t bytes = *size * sizeof(int);
const int result = CopyOut(entry.mib, entry.length * sizeof(int), mib, &bytes);
*size = bytes / sizeof(int);
return result;
}
throw std::runtime_error(std::string(__func__) + ": unsupported name " + name);
}
}
94 changes: 94 additions & 0 deletions core/libs/tests/GuestSystemConfiguration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ int APS5_VABI getpagesize_nid_postfix();
int* APS5_VABI __error_nid_postfix();
int APS5_VABI sysctl_nid_postfix(const int*, std::uint32_t, void*, std::size_t*, const void*, std::size_t);
int APS5_VABI sysctlbyname_nid_postfix(const char*, void*, std::size_t*, const void*, std::size_t);
int APS5_VABI sysctlnametomib_nid_postfix(const char*, int*, std::size_t*);
int APS5_VABI sceKernelGetSystemSwVersion_nid_postfix(SceKernelSystemSwVersion*);
int APS5_VABI getpid_nid_postfix();
std::uint64_t APS5_VABI sceKernelGetTscFrequency(void);
Expand Down Expand Up @@ -301,6 +302,98 @@ static void CheckArandomSysctl() {
Require(sysctl_nid_postfix(mib, 2, first, nullptr, nullptr, 0) == 0);
Require(*__error_nid_postfix() == 13);
}
static void CheckNameToMib() {
struct Expected {
const char* name;
int mib[3];
std::size_t length;
};
const Expected expected[] = {
{"hw.model", {6, 2}, 2},
{"hw.ncpu", {6, 3}, 2},
{"hw.physmem", {6, 5}, 2},
{"hw.realmem", {6, 12}, 2},
{"kern.arandom", {1, 37}, 2},
{"kern.proc.pathname", {1, 14, 12}, 3},
};
*__error_nid_postfix() = 13;
for (const auto& entry : expected) {
std::size_t size = 0;
Require(sysctlnametomib_nid_postfix(entry.name, nullptr, &size) == 0 && size == entry.length);
int mib[5] = {0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a};
size = 5;
Require(sysctlnametomib_nid_postfix(entry.name, mib, &size) == 0 && size == entry.length);
Require(std::memcmp(mib, entry.mib, entry.length * sizeof(int)) == 0 && mib[entry.length] == 0x5a5a5a5a);
}
Require(*__error_nid_postfix() == 13);

int mib[4] = {};
std::size_t size = 4;
Require(sysctlnametomib_nid_postfix("hw.ncpu", mib, &size) == 0 && size == 2);
int processors = 0;
std::size_t length = sizeof(processors);
Require(sysctl_nid_postfix(mib, static_cast<std::uint32_t>(size), &processors, &length, nullptr, 0) == 0);
Require(processors == static_cast<int>(sysconf_nid_postfix(58)));
size = 4;
Require(sysctlnametomib_nid_postfix("hw.realmem", mib, &size) == 0 && size == 2);
std::uint64_t realmem = 0;
length = sizeof(realmem);
Require(sysctl_nid_postfix(mib, static_cast<std::uint32_t>(size), &realmem, &length, nullptr, 0) == 0);
std::uint64_t namedRealmem = 0;
length = sizeof(namedRealmem);
Require(sysctlbyname_nid_postfix("hw.realmem", &namedRealmem, &length, nullptr, 0) == 0 && realmem == namedRealmem);
size = 4;
Require(sysctlnametomib_nid_postfix("kern.proc.pathname", mib, &size) == 0 && size == 3);
mib[3] = -1;
char path[32] = {};
length = sizeof(path);
Require(sysctl_nid_postfix(mib, 4, path, &length, nullptr, 0) == 0 && std::strcmp(path, "/app0/eboot.bin") == 0);

int truncated[3] = {0x5a5a5a5a, 0x5a5a5a5a, 0x5a5a5a5a};
size = 1;
Require(sysctlnametomib_nid_postfix("hw.ncpu", truncated, &size) == -1 && *__error_nid_postfix() == 12);
Require(size == 1 && truncated[0] == 6 && truncated[1] == 0x5a5a5a5a);
size = 0;
Require(sysctlnametomib_nid_postfix("hw.ncpu", truncated, &size) == -1 && *__error_nid_postfix() == 12);
Require(size == 0 && truncated[0] == 6);

size = 4;
Require(sysctlnametomib_nid_postfix("", mib, &size) == -1 && *__error_nid_postfix() == 2);
Require(sysctlnametomib_nid_postfix("machdep.cacheline_size", mib, &size) == -1 && *__error_nid_postfix() == 2);
char tooLong[1025];
std::memset(tooLong, 'a', sizeof(tooLong) - 1);
tooLong[sizeof(tooLong) - 1] = 0;
Require(sysctlnametomib_nid_postfix(tooLong, mib, &size) == -1 && *__error_nid_postfix() == 63);
tooLong[1023] = 0;
bool threw = false;
try {
sysctlnametomib_nid_postfix(tooLong, mib, &size);
} catch (const std::runtime_error&) {
threw = true;
}
Require(threw);
threw = false;
try {
sysctlnametomib_nid_postfix(nullptr, mib, &size);
} catch (const std::invalid_argument&) {
threw = true;
}
Require(threw);
threw = false;
try {
sysctlnametomib_nid_postfix("hw.ncpu", mib, nullptr);
} catch (const std::invalid_argument&) {
threw = true;
}
Require(threw);
threw = false;
try {
sysctlnametomib_nid_postfix("kern.cp_times", mib, &size);
} catch (const std::runtime_error&) {
threw = true;
}
Require(threw);
}
int main() {
CheckProcessorCountSysctl();
CheckPhysicalMemorySysctl(5, "hw.physmem");
Expand All @@ -317,6 +410,7 @@ int main() {
CheckSdkVersionSysctl();
CheckOvercommitSysctl();
CheckArandomSysctl();
CheckNameToMib();
*__error_nid_postfix() = 13;
Require(sysconf_nid_postfix(3) == 128);
Require(sysconf_nid_postfix(47) == 0x4000);
Expand Down
Loading