From 3df3e98f32d4aadc0c6579aff651322cfb2e596b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alf-Andr=C3=A9=20Walla?= Date: Wed, 31 Jul 2024 22:24:32 +0200 Subject: [PATCH] Add support for PACKED_FLOAT32_ARRAY and PACKED_FLOAT64_ARRAY --- CMakeLists.txt | 2 ++ program/variant.hpp | 32 ++++++++++++++++++++++++++++++++ src/gvar.cpp | 32 ++++++++++++++++++++++++++++++++ src/sandbox.hpp | 21 ++++++++++++++++++++- src/sandbox_functions.cpp | 4 ++-- 5 files changed, 88 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c5a989b1..0cf78593 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,8 @@ option(STATIC_BUILD "Build statically" OFF) set(SOURCES src/gvar.cpp src/register_types.cpp + src/resource_cpp.cpp + src/resource_loader_cpp.cpp src/resource_elf.cpp src/resource_loader_elf.cpp src/sandbox.cpp diff --git a/program/variant.hpp b/program/variant.hpp index 74ce65f4..e23d55ad 100644 --- a/program/variant.hpp +++ b/program/variant.hpp @@ -4,6 +4,7 @@ #include #include #include +#include template struct is_string @@ -146,6 +147,9 @@ struct Variant operator std::string_view() const; // View for STRING and PACKED_BYTE_ARRAY operator std::span() const; // Modifiable span for PACKED_BYTE_ARRAY + std::vector& f32array() const; // Modifiable vector for PACKED_FLOAT32_ARRAY + std::vector& f64array() const; // Modifiable vector for PACKED_FLOAT64_ARRAY + void callp(const std::string &method, const Variant *args, int argcount, Variant &r_ret, int &r_error); template @@ -185,6 +189,8 @@ struct Variant int64_t i; double f; std::string *s; + std::vector *f32array; + std::vector *f64array; } v; }; @@ -286,11 +292,29 @@ inline Variant::operator std::span() const throw std::bad_cast(); } +inline std::vector& Variant::f32array() const +{ + if (m_type == PACKED_FLOAT32_ARRAY) + return *v.f32array; + throw std::bad_cast(); +} + +inline std::vector& Variant::f64array() const +{ + if (m_type == PACKED_FLOAT64_ARRAY) + return *v.f64array; + throw std::bad_cast(); +} + inline Variant::Variant(const Variant &other) { m_type = other.m_type; if (m_type == STRING || m_type == PACKED_BYTE_ARRAY) v.s = new std::string(*other.v.s); + else if (m_type == PACKED_FLOAT32_ARRAY) + v.f32array = new std::vector(*other.v.f32array); + else if (m_type == PACKED_FLOAT64_ARRAY) + v.f64array = new std::vector(*other.v.f64array); else v = other.v; } @@ -305,12 +329,20 @@ inline Variant::~Variant() { if (m_type == STRING || m_type == PACKED_BYTE_ARRAY) delete v.s; + else if (m_type == PACKED_FLOAT32_ARRAY) + delete v.f32array; + else if (m_type == PACKED_FLOAT64_ARRAY) + delete v.f64array; } inline Variant &Variant::operator=(const Variant &other) { m_type = other.m_type; if (m_type == STRING || m_type == PACKED_BYTE_ARRAY) v.s = new std::string(*other.v.s); + else if (m_type == PACKED_FLOAT32_ARRAY) + v.f32array = new std::vector(*other.v.f32array); + else if (m_type == PACKED_FLOAT64_ARRAY) + v.f64array = new std::vector(*other.v.f64array); else v = other.v; diff --git a/src/gvar.cpp b/src/gvar.cpp index fa969433..b5633710 100644 --- a/src/gvar.cpp +++ b/src/gvar.cpp @@ -58,6 +58,16 @@ Variant GuestVariant::toVariant(const Sandbox &emu) const { } return Variant{ std::move(array) }; } + case Variant::PACKED_FLOAT32_ARRAY: { + auto *gvec = emu.machine().memory.memarray(v.vf32); + auto &vec = (*gvec)[0]; + return Variant{ vec.to_f32array(emu.machine()) }; + } + case Variant::PACKED_FLOAT64_ARRAY: { + auto *gvec = emu.machine().memory.memarray(v.vf64); + auto &vec = (*gvec)[0]; + return Variant{ vec.to_f64array(emu.machine()) }; + } default: ERR_PRINT(("GuestVariant::toVariant(): Unsupported type: " + std::to_string(type)).c_str()); return Variant(); @@ -169,6 +179,28 @@ void GuestVariant::set(Sandbox &emu, const Variant &value) { this->v.s = ptr; break; } + case Variant::PACKED_FLOAT32_ARRAY: { + auto arr = value.operator godot::PackedFloat32Array(); + auto ptr = emu.machine().arena().malloc(sizeof(GuestStdVector)); + auto *gvec = emu.machine().memory.memarray(ptr, 1); + gvec->ptr = emu.machine().arena().malloc(arr.size() * sizeof(float)); + gvec->size = arr.size(); + gvec->capacity = arr.size(); + std::memcpy(emu.machine().memory.memarray(gvec->ptr, arr.size()), arr.ptr(), arr.size() * sizeof(float)); + this->v.vf32 = ptr; + break; + } + case Variant::PACKED_FLOAT64_ARRAY: { + auto arr = value.operator godot::PackedFloat64Array(); + auto ptr = emu.machine().arena().malloc(sizeof(GuestStdVector)); + auto *gvec = emu.machine().memory.memarray(ptr, 1); + gvec->ptr = emu.machine().arena().malloc(arr.size() * sizeof(double)); + gvec->size = arr.size(); + gvec->capacity = arr.size(); + std::memcpy(emu.machine().memory.memarray(gvec->ptr, arr.size()), arr.ptr(), arr.size() * sizeof(double)); + this->v.vf64 = ptr; + break; + } default: ERR_PRINT(("SetVariant(): Unsupported type: " + std::to_string(value.get_type())).c_str()); } diff --git a/src/sandbox.hpp b/src/sandbox.hpp index 73758f34..22380eb8 100644 --- a/src/sandbox.hpp +++ b/src/sandbox.hpp @@ -151,6 +151,23 @@ struct GuestStdVector const T* array = machine.memory.memarray(ptr, size); return std::vector(array, size); } + + PackedFloat32Array to_f32array(const machine_t& machine) const + { + PackedFloat32Array array; + array.resize(this->size); + const float *fptr = machine.memory.memarray(this->ptr, this->size); + std::memcpy(array.ptrw(), fptr, this->size * sizeof(float)); + return array; + } + PackedFloat64Array to_f64array(const machine_t& machine) const + { + PackedFloat64Array array; + array.resize(this->size); + const double *fptr = machine.memory.memarray(this->ptr, this->size); + std::memcpy(array.ptrw(), fptr, this->size * sizeof(double)); + return array; + } }; struct GuestVariant { @@ -167,7 +184,9 @@ struct GuestVariant { bool b; int64_t i; double f; - gaddr_t s; + gaddr_t s; // String & PackedByteArray -> GuestStdString + gaddr_t vf32; // PackedFloat32Array -> GuestStdVector + gaddr_t vf64; // PackedFloat64Array -> GuestStdVector std::array v2f; std::array v3f; std::array v4f; diff --git a/src/sandbox_functions.cpp b/src/sandbox_functions.cpp index 9bdc0f0b..a5ef8368 100644 --- a/src/sandbox_functions.cpp +++ b/src/sandbox_functions.cpp @@ -3,14 +3,14 @@ #include using namespace godot; -static const std::unordered_set exclude_functions{ "btree_node_update_separator_after_split", "frame_downheap", "version_lock_lock_exclusive", "read_encoded_value_with_base", "fde_unencoded_extract", "fde_radixsort", "fde_unencoded_compare", "version_lock_unlock_exclusive", "btree_allocate_node", "btree_handle_root_split.part.0", "btree_insert.isra.0", "btree_release_tree_recursively", "btree_destroy", "get_cie_encoding", "btree_remove", "fde_mixed_encoding_extract", "classify_object_over_fdes", "get_pc_range", "fde_single_encoding_extract", "fde_single_encoding_compare", "fde_mixed_encoding_compare", "add_fdes.isra.0", "linear_search_fdes", "release_registered_frames", "deregister_tm_clones", "register_tm_clones", "frame_dummy", "d_make_comp", "d_number", "d_call_offset", "d_discriminator", "d_count_templates_scopes", "d_pack_length", "d_index_template_argument.part.0", "d_growable_string_callback_adapter", "next_is_type_qual.isra.0", "d_append_char", "d_lookup_template_argument", "d_find_pack", "d_append_string", "d_template_param", "d_append_num", "d_print_lambda_parm_name", "d_source_name", "d_substitution", "d_maybe_module_name", "d_type", "d_cv_qualifiers", "d_function_type", "d_name", "d_expression_1", "d_template_args_1", "d_parmlist", "d_bare_function_type", "d_template_parm", "d_template_head", "d_operator_name", "d_unqualified_name", "d_exprlist", "d_prefix", "d_expr_primary", "d_special_name", "d_encoding.part.0", "d_template_arg", "d_print_comp_inner", "d_print_comp", "d_print_mod", "d_print_array_type", "d_print_expr_op", "d_print_subexpr", "d_maybe_print_fold_expression", "d_maybe_print_designated_init", "d_print_function_type", "d_print_mod_list", "d_demangle_callback.constprop.0", "init_dwarf_reg_size_table", "uw_install_context_1", "read_encoded_value", "execute_stack_op", "uw_update_context_1", "execute_cfa_program_specialized", "execute_cfa_program_generic", "uw_frame_state_for", "uw_init_context_1", "call_fini", "check_one_fd", "new_do_write", "mmap_remap_check", "decide_maybe_mmap", "flush_cleanup", "save_for_backup", "enlarge_userbuf", "malloc_printerr", "int_mallinfo", "alloc_perturb", "munmap_chunk", "detach_arena.part.0", "unlink_chunk.isra.0", "malloc_consolidate", "ptmalloc_init.part.0", "alloc_new_heap", "new_heap", "arena_get2", "arena_get_retry", "sysmalloc_mmap_fallback.constprop.0", "sysmalloc_mmap.isra.0", "systrim.constprop.0", "sysmalloc", "tcache_init.part.0", "two_way_long_needle", "next_line", "read_sysfs_file", "get_nproc_stat", "do_tunable_update_val", "tunable_initialize", "parse_tunables", "elf_machine_matches_host", "free_derivation", "free_modules_db", "derivation_compare", "find_derivation", "insert_module", "add_module", "add_alias2.part.0", "read_conf_file.isra.0", "find_module_idx", "find_module.constprop.0", "known_compare", "do_release_shlib", "do_release_all", "new_composite_name", "free_category", "plural_eval", "transcmp", "alias_compare", "read_alias_file", "do_swap", "msort_with_tmp.part.0", "indirect_msort_with_tmp", "read_int", "outstring_converted_wide_string", "group_number", "printf_positional", "read_int", "save_for_wbackup", "adjust_wide_data", "clear_once_control", "opendir_tail", "trecurse", "trecurse_r", "tdestroy_recurse", "maybe_split_for_insert.isra.0", "fatal_error", "length_mismatch", "is_dst", "is_trusted_path_normalize", "add_path.constprop.0.isra.0", "add_name_to_object.isra.0", "open_verify.constprop.0", "open_path.isra.0", "elf_machine_matches_host", "expand_dynamic_string_token", "fillin_rpath.isra.0", "decompose_rpath", "check_match", "do_lookup_x", "elf_machine_matches_host", "elf_machine_matches_host", "search_cache", "do_dlopen", "dlerror_run", "do_dlsym_private", "do_dlsym", "do_dlvsym", "do_dlclose", "free_slotinfo", "gconv_parse_code", "hack_digit", "two_way_long_needle", "remove_slotinfo", "call_dl_init", "add_to_global_update", "dl_open_worker", "dl_open_worker_begin", "add_to_global_resize_failure.isra.0", "add_to_global_resize", "elf_machine_matches_host", "dfs_traversal.part.0", "dlinfo_doit", "dlmopen_doit", "dlopen_doit", "dlsym_doit", "dlvsym_doit", "openaux", "call_init", "check_match", "call_dl_lookup", "do_sym", "base_of_encoded_value", "read_encoded_value_with_base", "stpcpy", "tsearch", "clock_gettime", "secure_getenv", "strcpy", "unsetenv", "gsignal", "bcmp", "setjmp", "getrlimit", "ioctl", "dlerror", "fstatat", "strtok_r", "dlinfo", "sysconf", "vsprintf", "getdtablesize", "fdopendir", "strtoull_l", "pthread_rwlock_rdlock", "memrchr", "strndup", "argz_add_sep", "stat64", "memmove", "pthread_rwlock_init", "getauxval", "snprintf", "munmap", "sched_getparam", "malloc_stats", "strtoimax", "getenv", "wcslen", "memmem", "wmempcpy", "sys_veval", "getpid", "getpagesize", "arc4random", "qsort", "dlmopen", "getrlimit64", "memcpy", "strtoll_l", "rewinddir", "sys_vcall", "malloc", "isatty", "openat64", "sched_setscheduler", "sysinfo", "vsnprintf", "strtoll", "register_printf_modifier", "strtoumax", "strtoul", "sched_getscheduler", "pthread_rwlock_unlock", "readdir", "pvalloc", "dladdr", "lseek", "wmemcpy", "clearenv", "mmap", "strtol_l", "dlclose", "abort", "sys_print", "fstat64", "tdelete", "strtoq", "strtol", "strnlen", "strrchr", "calloc", "strcasecmp_l", "malloc_usable_size", "tdestroy", "rindex", "write", "dladdr1", "wmemchr", "fstat", "dcgettext", "pthread_once", "madvise", "mremap", "getdelim", "memchr", "tfind", "lstat", "strstr", "pthread_kill", "read", "getentropy", "strncmp", "dlopen", "wcsrtombs", "getdents64", "pthread_rwlock_wrlock", "get_avphys_pages", "setenv", "sched_get_priority_max", "funlockfile", "pthread_sigmask", "realloc", "readdir64", "wcsnlen", "register_printf_specifier", "memcmp", "sched_get_priority_min", "malloc_trim", "lstat64", "sigaction", "twalk_r", "dlsym", "sbrk", "strdup", "strtoull", "index", "fopen", "memset", "get_phys_pages", "mallinfo2", "mallopt", "fclose", "open64", "malloc_info", "tcgetattr", "opendir", "strcmp", "pthread_mutex_unlock", "register_printf_function", "strtoul_l", "getcwd", "fstatat64", "memalign", "asprintf", "strerror_r", "strcspn", "setlocale", "mmap64", "strsep", "valloc", "dlvsym", "fputc", "register_printf_type", "mallinfo", "pthread_self", "twalk", "argz_create_sep", "stat", "fast_exit", "wmemmove", "fwrite", "qsort_r", "strtouq", "pthread_mutex_lock", "gettext", "get_nprocs", "exit", "brk", "openat", "fgets_unlocked", "strspn", "strlen", "lseek64", "open", "strchr", "arc4random_buf", "fputs", "mprotect", "closedir", "vasprintf", "strchrnul", "get_nprocs_conf", "aligned_alloc", "posix_memalign", "wcrtomb", "close", "raise", "free", "sigprocmask", "fopen64" }; +static const std::unordered_set exclude_functions{ "btree_node_update_separator_after_split", "frame_downheap", "version_lock_lock_exclusive", "read_encoded_value_with_base", "fde_unencoded_extract", "fde_radixsort", "fde_unencoded_compare", "version_lock_unlock_exclusive", "btree_allocate_node", "btree_handle_root_split.part.0", "btree_insert.isra.0", "btree_release_tree_recursively", "btree_destroy", "get_cie_encoding", "btree_remove", "fde_mixed_encoding_extract", "classify_object_over_fdes", "get_pc_range", "fde_single_encoding_extract", "fde_single_encoding_compare", "fde_mixed_encoding_compare", "add_fdes.isra.0", "linear_search_fdes", "release_registered_frames", "deregister_tm_clones", "register_tm_clones", "frame_dummy", "d_make_comp", "d_number", "d_call_offset", "d_discriminator", "d_count_templates_scopes", "d_pack_length", "d_index_template_argument.part.0", "d_growable_string_callback_adapter", "next_is_type_qual.isra.0", "d_append_char", "d_lookup_template_argument", "d_find_pack", "d_append_string", "d_template_param", "d_append_num", "d_print_lambda_parm_name", "d_source_name", "d_substitution", "d_maybe_module_name", "d_type", "d_cv_qualifiers", "d_function_type", "d_name", "d_expression_1", "d_template_args_1", "d_parmlist", "d_bare_function_type", "d_template_parm", "d_template_head", "d_operator_name", "d_unqualified_name", "d_exprlist", "d_prefix", "d_expr_primary", "d_special_name", "d_encoding.part.0", "d_template_arg", "d_print_comp_inner", "d_print_comp", "d_print_mod", "d_print_array_type", "d_print_expr_op", "d_print_subexpr", "d_maybe_print_fold_expression", "d_maybe_print_designated_init", "d_print_function_type", "d_print_mod_list", "d_demangle_callback.constprop.0", "init_dwarf_reg_size_table", "uw_install_context_1", "read_encoded_value", "execute_stack_op", "uw_update_context_1", "execute_cfa_program_specialized", "execute_cfa_program_generic", "uw_frame_state_for", "uw_init_context_1", "call_fini", "check_one_fd", "new_do_write", "mmap_remap_check", "decide_maybe_mmap", "flush_cleanup", "save_for_backup", "enlarge_userbuf", "malloc_printerr", "int_mallinfo", "alloc_perturb", "munmap_chunk", "detach_arena.part.0", "unlink_chunk.isra.0", "malloc_consolidate", "ptmalloc_init.part.0", "alloc_new_heap", "new_heap", "arena_get2", "arena_get_retry", "sysmalloc_mmap_fallback.constprop.0", "sysmalloc_mmap.isra.0", "systrim.constprop.0", "sysmalloc", "tcache_init.part.0", "two_way_long_needle", "next_line", "read_sysfs_file", "get_nproc_stat", "do_tunable_update_val", "tunable_initialize", "parse_tunables", "elf_machine_matches_host", "free_derivation", "free_modules_db", "derivation_compare", "find_derivation", "insert_module", "add_module", "add_alias2.part.0", "read_conf_file.isra.0", "find_module_idx", "find_module.constprop.0", "known_compare", "do_release_shlib", "do_release_all", "new_composite_name", "free_category", "plural_eval", "transcmp", "alias_compare", "read_alias_file", "do_swap", "msort_with_tmp.part.0", "indirect_msort_with_tmp", "read_int", "outstring_converted_wide_string", "group_number", "printf_positional", "read_int", "save_for_wbackup", "adjust_wide_data", "clear_once_control", "opendir_tail", "trecurse", "trecurse_r", "tdestroy_recurse", "maybe_split_for_insert.isra.0", "fatal_error", "length_mismatch", "is_dst", "is_trusted_path_normalize", "add_path.constprop.0.isra.0", "add_name_to_object.isra.0", "open_verify.constprop.0", "open_path.isra.0", "elf_machine_matches_host", "expand_dynamic_string_token", "fillin_rpath.isra.0", "decompose_rpath", "check_match", "do_lookup_x", "elf_machine_matches_host", "elf_machine_matches_host", "search_cache", "do_dlopen", "dlerror_run", "do_dlsym_private", "do_dlsym", "do_dlvsym", "do_dlclose", "free_slotinfo", "gconv_parse_code", "hack_digit", "two_way_long_needle", "remove_slotinfo", "call_dl_init", "add_to_global_update", "dl_open_worker", "dl_open_worker_begin", "add_to_global_resize_failure.isra.0", "add_to_global_resize", "elf_machine_matches_host", "dfs_traversal.part.0", "dlinfo_doit", "dlmopen_doit", "dlopen_doit", "dlsym_doit", "dlvsym_doit", "openaux", "call_init", "check_match", "call_dl_lookup", "do_sym", "base_of_encoded_value", "read_encoded_value_with_base", "stpcpy", "tsearch", "clock_gettime", "secure_getenv", "strcpy", "unsetenv", "gsignal", "bcmp", "setjmp", "getrlimit", "ioctl", "dlerror", "fstatat", "strtok_r", "dlinfo", "sysconf", "vsprintf", "getdtablesize", "fdopendir", "strtoull_l", "pthread_rwlock_rdlock", "memrchr", "strndup", "argz_add_sep", "stat64", "memmove", "pthread_rwlock_init", "getauxval", "snprintf", "munmap", "sched_getparam", "malloc_stats", "strtoimax", "getenv", "wcslen", "memmem", "wmempcpy", "sys_veval", "getpid", "getpagesize", "arc4random", "qsort", "dlmopen", "getrlimit64", "memcpy", "strtoll_l", "rewinddir", "sys_vcall", "malloc", "isatty", "openat64", "sched_setscheduler", "sysinfo", "vsnprintf", "strtoll", "register_printf_modifier", "strtoumax", "strtoul", "sched_getscheduler", "pthread_rwlock_unlock", "readdir", "pvalloc", "dladdr", "lseek", "wmemcpy", "clearenv", "mmap", "strtol_l", "dlclose", "abort", "sys_print", "fstat64", "tdelete", "strtoq", "strtol", "strnlen", "strrchr", "calloc", "strcasecmp_l", "malloc_usable_size", "tdestroy", "rindex", "write", "dladdr1", "wmemchr", "fstat", "dcgettext", "pthread_once", "madvise", "mremap", "getdelim", "memchr", "tfind", "lstat", "strstr", "pthread_kill", "read", "getentropy", "strncmp", "dlopen", "wcsrtombs", "getdents64", "pthread_rwlock_wrlock", "get_avphys_pages", "setenv", "sched_get_priority_max", "funlockfile", "pthread_sigmask", "realloc", "readdir64", "wcsnlen", "register_printf_specifier", "memcmp", "sched_get_priority_min", "malloc_trim", "lstat64", "sigaction", "twalk_r", "dlsym", "sbrk", "strdup", "strtoull", "index", "fopen", "memset", "get_phys_pages", "mallinfo2", "mallopt", "fclose", "open64", "malloc_info", "tcgetattr", "opendir", "strcmp", "pthread_mutex_unlock", "register_printf_function", "strtoul_l", "getcwd", "fstatat64", "memalign", "asprintf", "strerror_r", "strcspn", "setlocale", "mmap64", "strsep", "valloc", "dlvsym", "fputc", "register_printf_type", "mallinfo", "pthread_self", "twalk", "argz_create_sep", "stat", "fast_exit", "wmemmove", "fwrite", "qsort_r", "strtouq", "pthread_mutex_lock", "gettext", "get_nprocs", "exit", "brk", "openat", "fgets_unlocked", "strspn", "strlen", "lseek64", "open", "strchr", "arc4random_buf", "fputs", "mprotect", "closedir", "vasprintf", "strchrnul", "get_nprocs_conf", "aligned_alloc", "posix_memalign", "wcrtomb", "close", "raise", "free", "sigprocmask", "fopen64" }; PackedStringArray Sandbox::get_functions() const { PackedStringArray array; // Get all unmangled public functions from the guest program. for (auto &functions : machine().memory.all_unmangled_function_symbols()) { // Exclude functions that belong to the C/C++ runtime, as well as compiler-generated functions. - if (exclude_functions.count(std::string(functions)) == 0) { + if (exclude_functions.count(functions) == 0) { array.append(String(std::string(functions).c_str())); } }