mirror of
https://github.com/asmjit/asmjit.git
synced 2025-12-16 20:17:05 +03:00
Added asmjit_environment_info executable
This commit is contained in:
@@ -628,7 +628,8 @@ if (NOT ASMJIT_EMBED)
|
||||
|
||||
foreach(_target asmjit_test_emitters
|
||||
asmjit_test_execute
|
||||
asmjit_test_x86_sections)
|
||||
asmjit_test_x86_sections
|
||||
asmjit_environment_info)
|
||||
asmjit_add_target(${_target} TEST
|
||||
SOURCES test/${_target}.cpp
|
||||
LIBRARIES asmjit::asmjit
|
||||
|
||||
97
test/asmjit_environment_info.cpp
Normal file
97
test/asmjit_environment_info.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
// This file is part of AsmJit project <https://asmjit.com>
|
||||
//
|
||||
// See asmjit.h or LICENSE.md for license and copyright information
|
||||
// SPDX-License-Identifier: Zlib
|
||||
|
||||
#include <asmjit/core.h>
|
||||
|
||||
#include "asmjitutils.h"
|
||||
|
||||
using namespace asmjit;
|
||||
|
||||
#if !defined(ASMJIT_NO_JIT)
|
||||
static void printVirtMemInfo() {
|
||||
using MemoryFlags = VirtMem::MemoryFlags;
|
||||
using HardenedRuntimeInfo = VirtMem::HardenedRuntimeInfo;
|
||||
using HardenedRuntimeFlags = VirtMem::HardenedRuntimeFlags;
|
||||
|
||||
constexpr size_t kVMemAllocSize = 65536;
|
||||
|
||||
auto stringifyBool = [](bool b) { return b ? "true" : "false"; };
|
||||
auto stringifySuccess = [](bool b) { return b ? "success" : "failure"; };
|
||||
|
||||
HardenedRuntimeInfo rti = VirtMem::hardenedRuntimeInfo();
|
||||
|
||||
printf("Hardened Environment Info:\n");
|
||||
printf(" Hardening was detected : %s\n", stringifyBool(rti.hasFlag(HardenedRuntimeFlags::kEnabled )));
|
||||
printf(" MAP_JIT is available : %s\n", stringifyBool(rti.hasFlag(HardenedRuntimeFlags::kMapJit )));
|
||||
printf(" DualMapping is available: %s\n", stringifyBool(rti.hasFlag(HardenedRuntimeFlags::kDualMapping)));
|
||||
printf("\n");
|
||||
|
||||
printf("Executable Memory Allocation:\n");
|
||||
|
||||
{
|
||||
void* ptr = nullptr;
|
||||
Error result = VirtMem::alloc(&ptr, kVMemAllocSize, MemoryFlags::kAccessRWX);
|
||||
printf(" Allocation of RWX memory: %s\n", stringifySuccess(result == kErrorOk));
|
||||
|
||||
if (result == kErrorOk) {
|
||||
result = VirtMem::release(ptr, kVMemAllocSize);
|
||||
printf(" Release of RWX memory : %s\n", stringifySuccess(result == kErrorOk));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
void* ptr = nullptr;
|
||||
Error result = VirtMem::alloc(&ptr, kVMemAllocSize, MemoryFlags::kAccessRW | MemoryFlags::kMMapMaxAccessRWX);
|
||||
printf(" Allocation of RW_ memory: %s (allocation uses kMMapMaxAccessRWX)\n", stringifySuccess(result == kErrorOk));
|
||||
|
||||
if (result == kErrorOk) {
|
||||
result = VirtMem::protect(ptr, kVMemAllocSize, MemoryFlags::kAccessRX);
|
||||
printf(" Change Access {RW -> RX}: %s\n", stringifySuccess(result == kErrorOk));
|
||||
|
||||
result = VirtMem::protect(ptr, kVMemAllocSize, MemoryFlags::kAccessRW);
|
||||
printf(" Change Access {RX -> RW}: %s\n", stringifySuccess(result == kErrorOk));
|
||||
|
||||
result = VirtMem::release(ptr, kVMemAllocSize);
|
||||
printf(" Release of RW memory : %s\n", stringifySuccess(result == kErrorOk));
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
VirtMem::DualMapping dm {};
|
||||
Error result = VirtMem::allocDualMapping(&dm, kVMemAllocSize, MemoryFlags::kAccessRWX);
|
||||
printf(" Dual mapping RWX alloc : %s\n", stringifySuccess(result == kErrorOk));
|
||||
|
||||
if (result == kErrorOk) {
|
||||
result = VirtMem::releaseDualMapping(&dm, kVMemAllocSize);
|
||||
printf(" Dual mapping RWX release: %s\n", stringifySuccess(result == kErrorOk));
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
#endif // ASMJIT_NO_JIT
|
||||
|
||||
int main() {
|
||||
printf("AsmJit Environment Info v%u.%u.%u [Arch=%s]\n\n",
|
||||
unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
|
||||
unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF),
|
||||
unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF),
|
||||
asmjitArchAsString(Arch::kHost)
|
||||
);
|
||||
|
||||
printf("This application can be used to verify AsmJit build options and to verify the\n");
|
||||
printf("environment where it runs. For example to check CPU extensions available, OS\n");
|
||||
printf("hardening and virtual memory allocation options.\n");
|
||||
printf("\n");
|
||||
|
||||
printBuildOptions();
|
||||
printCpuInfo();
|
||||
|
||||
#if !defined(ASMJIT_NO_JIT)
|
||||
printVirtMemInfo();
|
||||
#endif // ASMJIT_NO_JIT
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -9,51 +9,20 @@
|
||||
#include <asmjit/x86.h>
|
||||
#endif
|
||||
|
||||
#if !defined(ASMJIT_NO_AARCH64)
|
||||
#include <asmjit/a64.h>
|
||||
#endif
|
||||
|
||||
#include "asmjitutils.h"
|
||||
#include "broken.h"
|
||||
|
||||
using namespace asmjit;
|
||||
|
||||
static void dumpCpu(void) noexcept {
|
||||
const CpuInfo& cpu = CpuInfo::host();
|
||||
|
||||
// CPU Information
|
||||
// ---------------
|
||||
|
||||
INFO("CPU Info:");
|
||||
INFO(" Vendor : %s", cpu.vendor());
|
||||
INFO(" Brand : %s", cpu.brand());
|
||||
INFO(" Model ID : %u", cpu.modelId());
|
||||
INFO(" Brand ID : %u", cpu.brandId());
|
||||
INFO(" Family ID : %u", cpu.familyId());
|
||||
INFO(" Stepping : %u", cpu.stepping());
|
||||
INFO(" Processor Type : %u", cpu.processorType());
|
||||
INFO(" Max logical Processors : %u", cpu.maxLogicalProcessors());
|
||||
INFO(" Cache-Line Size : %u", cpu.cacheLineSize());
|
||||
INFO(" HW-Thread Count : %u", cpu.hwThreadCount());
|
||||
INFO("");
|
||||
|
||||
// CPU Features
|
||||
// ------------
|
||||
|
||||
#ifndef ASMJIT_NO_LOGGING
|
||||
INFO("CPU Features:");
|
||||
CpuFeatures::Iterator it(cpu.features().iterator());
|
||||
while (it.hasNext()) {
|
||||
uint32_t featureId = uint32_t(it.next());
|
||||
StringTmp<64> featureString;
|
||||
Formatter::formatFeature(featureString, cpu.arch(), featureId);
|
||||
INFO(" %s\n", featureString.data());
|
||||
};
|
||||
INFO("");
|
||||
#endif // !ASMJIT_NO_LOGGING
|
||||
}
|
||||
|
||||
#define DUMP_TYPE(...) \
|
||||
INFO(" %-26s: %u", #__VA_ARGS__, uint32_t(sizeof(__VA_ARGS__)))
|
||||
printf(" %-26s: %u\n", #__VA_ARGS__, uint32_t(sizeof(__VA_ARGS__)))
|
||||
|
||||
static void dumpSizeOf(void) noexcept {
|
||||
INFO("Size of C++ types:");
|
||||
static void printTypeSizes(void) noexcept {
|
||||
printf("Size of C++ types:\n");
|
||||
DUMP_TYPE(int8_t);
|
||||
DUMP_TYPE(int16_t);
|
||||
DUMP_TYPE(int32_t);
|
||||
@@ -65,9 +34,9 @@ static void dumpSizeOf(void) noexcept {
|
||||
DUMP_TYPE(float);
|
||||
DUMP_TYPE(double);
|
||||
DUMP_TYPE(void*);
|
||||
INFO("");
|
||||
printf("\n");
|
||||
|
||||
INFO("Size of base classes:");
|
||||
printf("Size of base classes:\n");
|
||||
DUMP_TYPE(BaseAssembler);
|
||||
DUMP_TYPE(BaseEmitter);
|
||||
DUMP_TYPE(CodeBuffer);
|
||||
@@ -85,27 +54,27 @@ static void dumpSizeOf(void) noexcept {
|
||||
DUMP_TYPE(ZoneHash<ZoneHashNode>);
|
||||
DUMP_TYPE(ZoneList<int>);
|
||||
DUMP_TYPE(ZoneVector<int>);
|
||||
INFO("");
|
||||
printf("\n");
|
||||
|
||||
INFO("Size of operand classes:");
|
||||
printf("Size of operand classes:\n");
|
||||
DUMP_TYPE(Operand);
|
||||
DUMP_TYPE(BaseReg);
|
||||
DUMP_TYPE(BaseMem);
|
||||
DUMP_TYPE(Imm);
|
||||
DUMP_TYPE(Label);
|
||||
INFO("");
|
||||
printf("\n");
|
||||
|
||||
INFO("Size of function classes:");
|
||||
printf("Size of function classes:\n");
|
||||
DUMP_TYPE(CallConv);
|
||||
DUMP_TYPE(FuncFrame);
|
||||
DUMP_TYPE(FuncValue);
|
||||
DUMP_TYPE(FuncDetail);
|
||||
DUMP_TYPE(FuncSignature);
|
||||
DUMP_TYPE(FuncArgsAssignment);
|
||||
INFO("");
|
||||
printf("\n");
|
||||
|
||||
#if !defined(ASMJIT_NO_BUILDER)
|
||||
INFO("Size of builder classes:");
|
||||
printf("Size of builder classes:\n");
|
||||
DUMP_TYPE(BaseBuilder);
|
||||
DUMP_TYPE(BaseNode);
|
||||
DUMP_TYPE(InstNode);
|
||||
@@ -118,20 +87,20 @@ static void dumpSizeOf(void) noexcept {
|
||||
DUMP_TYPE(ConstPoolNode);
|
||||
DUMP_TYPE(CommentNode);
|
||||
DUMP_TYPE(SentinelNode);
|
||||
INFO("");
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
#if !defined(ASMJIT_NO_COMPILER)
|
||||
INFO("Size of compiler classes:");
|
||||
printf("Size of compiler classes:\n");
|
||||
DUMP_TYPE(BaseCompiler);
|
||||
DUMP_TYPE(FuncNode);
|
||||
DUMP_TYPE(FuncRetNode);
|
||||
DUMP_TYPE(InvokeNode);
|
||||
INFO("");
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
#if !defined(ASMJIT_NO_X86)
|
||||
INFO("Size of x86-specific classes:");
|
||||
printf("Size of x86-specific classes:\n");
|
||||
DUMP_TYPE(x86::Assembler);
|
||||
#if !defined(ASMJIT_NO_BUILDER)
|
||||
DUMP_TYPE(x86::Builder);
|
||||
@@ -143,15 +112,28 @@ static void dumpSizeOf(void) noexcept {
|
||||
DUMP_TYPE(x86::InstDB::CommonInfo);
|
||||
DUMP_TYPE(x86::InstDB::OpSignature);
|
||||
DUMP_TYPE(x86::InstDB::InstSignature);
|
||||
INFO("");
|
||||
printf("\n");
|
||||
#endif
|
||||
|
||||
#if !defined(ASMJIT_NO_AARCH64)
|
||||
printf("Size of aarch64-specific classes:\n");
|
||||
DUMP_TYPE(a64::Assembler);
|
||||
#if !defined(ASMJIT_NO_BUILDER)
|
||||
DUMP_TYPE(a64::Builder);
|
||||
#endif
|
||||
#if !defined(ASMJIT_NO_COMPILER)
|
||||
DUMP_TYPE(a64::Compiler);
|
||||
#endif
|
||||
printf("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef DUMP_TYPE
|
||||
|
||||
static void onBeforeRun(void) noexcept {
|
||||
dumpCpu();
|
||||
dumpSizeOf();
|
||||
printBuildOptions();
|
||||
printCpuInfo();
|
||||
printTypeSizes();
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[]) {
|
||||
@@ -161,7 +143,7 @@ int main(int argc, const char* argv[]) {
|
||||
const char buildType[] = "Release";
|
||||
#endif
|
||||
|
||||
INFO("AsmJit Unit-Test v%u.%u.%u [Arch=%s] [Mode=%s]\n\n",
|
||||
printf("AsmJit Unit-Test v%u.%u.%u [Arch=%s] [Mode=%s]\n\n",
|
||||
unsigned((ASMJIT_LIBRARY_VERSION >> 16) ),
|
||||
unsigned((ASMJIT_LIBRARY_VERSION >> 8) & 0xFF),
|
||||
unsigned((ASMJIT_LIBRARY_VERSION ) & 0xFF),
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
namespace {
|
||||
|
||||
[[maybe_unused]]
|
||||
static inline const char* asmjitArchAsString(asmjit::Arch arch) noexcept {
|
||||
static const char* asmjitArchAsString(asmjit::Arch arch) noexcept {
|
||||
switch (arch) {
|
||||
case asmjit::Arch::kX86 : return "X86";
|
||||
case asmjit::Arch::kX64 : return "X64";
|
||||
@@ -39,7 +39,7 @@ static inline const char* asmjitArchAsString(asmjit::Arch arch) noexcept {
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
static inline void printIndented(const char* str, size_t indent) noexcept {
|
||||
static void printIndented(const char* str, size_t indent) noexcept {
|
||||
const char* start = str;
|
||||
while (*str) {
|
||||
if (*str == '\n') {
|
||||
@@ -55,6 +55,148 @@ static inline void printIndented(const char* str, size_t indent) noexcept {
|
||||
printf("%*s%.*s\n", int(indent), "", int(size), start);
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
static void printCpuInfo() noexcept {
|
||||
const asmjit::CpuInfo& cpu = asmjit::CpuInfo::host();
|
||||
|
||||
// CPU Information
|
||||
// ---------------
|
||||
|
||||
printf("CPU Info:\n");
|
||||
printf(" Vendor : %s\n", cpu.vendor());
|
||||
printf(" Brand : %s\n", cpu.brand());
|
||||
printf(" Model ID : %u\n", cpu.modelId());
|
||||
printf(" Brand ID : %u\n", cpu.brandId());
|
||||
printf(" Family ID : %u\n", cpu.familyId());
|
||||
printf(" Stepping : %u\n", cpu.stepping());
|
||||
printf(" Processor Type : %u\n", cpu.processorType());
|
||||
printf(" Max logical Processors : %u\n", cpu.maxLogicalProcessors());
|
||||
printf(" Cache-Line Size : %u\n", cpu.cacheLineSize());
|
||||
printf(" HW-Thread Count : %u\n", cpu.hwThreadCount());
|
||||
printf("\n");
|
||||
|
||||
// CPU Features
|
||||
// ------------
|
||||
|
||||
#ifndef ASMJIT_NO_LOGGING
|
||||
printf("CPU Features:\n");
|
||||
asmjit::CpuFeatures::Iterator it(cpu.features().iterator());
|
||||
while (it.hasNext()) {
|
||||
uint32_t featureId = uint32_t(it.next());
|
||||
asmjit::StringTmp<64> featureString;
|
||||
asmjit::Formatter::formatFeature(featureString, cpu.arch(), featureId);
|
||||
printf(" %s\n", featureString.data());
|
||||
};
|
||||
printf("\n");
|
||||
#endif // !ASMJIT_NO_LOGGING
|
||||
}
|
||||
|
||||
[[maybe_unused]]
|
||||
static void printBuildOptions() {
|
||||
auto stringifyBuildDefinition = [](bool b) { return b ? "defined" : "(not defined)"; };
|
||||
|
||||
#if defined(ASMJIT_BUILD_DEBUG)
|
||||
const char build_type[] = "Debug";
|
||||
#else
|
||||
const char build_type[] = "Release";
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_X86)
|
||||
constexpr bool no_x86 = true;
|
||||
#else
|
||||
constexpr bool no_x86 = false;
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_AARCH64)
|
||||
constexpr bool no_aarch64 = true;
|
||||
#else
|
||||
constexpr bool no_aarch64 = false;
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_FOREIGN)
|
||||
constexpr bool no_foreign = true;
|
||||
#else
|
||||
constexpr bool no_foreign = false;
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_DEPRECATED)
|
||||
constexpr bool no_deprecated = true;
|
||||
#else
|
||||
constexpr bool no_deprecated = false;
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_ABI_NAMESPACE)
|
||||
constexpr bool no_abi_namespace = true;
|
||||
#else
|
||||
constexpr bool no_abi_namespace = false;
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_SHM_OPEN)
|
||||
constexpr bool no_shm_open = true;
|
||||
#else
|
||||
constexpr bool no_shm_open = false;
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_JIT)
|
||||
constexpr bool no_jit = true;
|
||||
#else
|
||||
constexpr bool no_jit = false;
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_TEXT)
|
||||
constexpr bool no_text = true;
|
||||
#else
|
||||
constexpr bool no_text = false;
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_LOGGING)
|
||||
constexpr bool no_logging = true;
|
||||
#else
|
||||
constexpr bool no_logging = false;
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_VALIDATION)
|
||||
constexpr bool no_validation = true;
|
||||
#else
|
||||
constexpr bool no_validation = false;
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_INTROSPECTION)
|
||||
constexpr bool no_introspection = true;
|
||||
#else
|
||||
constexpr bool no_introspection = false;
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_BUILDER)
|
||||
constexpr bool no_builder = true;
|
||||
#else
|
||||
constexpr bool no_builder = false;
|
||||
#endif
|
||||
|
||||
#if defined(ASMJIT_NO_COMPILER)
|
||||
constexpr bool no_compiler = true;
|
||||
#else
|
||||
constexpr bool no_compiler = false;
|
||||
#endif
|
||||
|
||||
printf("Build Options:\n");
|
||||
printf(" Build Type : %s\n", build_type);
|
||||
printf(" ASMJIT_NO_X86 : %s\n", stringifyBuildDefinition(no_x86));
|
||||
printf(" ASMJIT_NO_AARCH64 : %s\n", stringifyBuildDefinition(no_aarch64));
|
||||
printf(" ASMJIT_NO_FOREIGN : %s\n", stringifyBuildDefinition(no_foreign));
|
||||
printf(" ASMJIT_NO_DEPRECATED : %s\n", stringifyBuildDefinition(no_deprecated));
|
||||
printf(" ASMJIT_NO_ABI_NAMESPACE: %s\n", stringifyBuildDefinition(no_abi_namespace));
|
||||
printf(" ASMJIT_NO_SHM_OPEN : %s\n", stringifyBuildDefinition(no_shm_open));
|
||||
printf(" ASMJIT_NO_JIT : %s\n", stringifyBuildDefinition(no_jit));
|
||||
printf(" ASMJIT_NO_TEXT : %s\n", stringifyBuildDefinition(no_text));
|
||||
printf(" ASMJIT_NO_LOGGING : %s\n", stringifyBuildDefinition(no_logging));
|
||||
printf(" ASMJIT_NO_VALIDATION : %s\n", stringifyBuildDefinition(no_validation));
|
||||
printf(" ASMJIT_NO_INTROSPECTION: %s\n", stringifyBuildDefinition(no_introspection));
|
||||
printf(" ASMJIT_NO_BUILDER : %s\n", stringifyBuildDefinition(no_builder));
|
||||
printf(" ASMJIT_NO_COMPILER : %s\n", stringifyBuildDefinition(no_compiler));
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
} // {anonymous}
|
||||
|
||||
#endif // ASMJITUTILS_H_INCLUDED
|
||||
|
||||
Reference in New Issue
Block a user