summaryrefslogtreecommitdiff
path: root/recipes/orc
diff options
context:
space:
mode:
authorNirbheek Chauhan <nirbheek@centricular.com>2020-07-01 19:03:53 +0530
committerNirbheek Chauhan <nirbheek@centricular.com>2020-07-01 21:00:22 +0530
commit02a99ad597d32994ee58d9dfcc354b3a4bb5a6ed (patch)
treeb60abb49010b411bb13439743efc1c72cd07dbbe /recipes/orc
parent109430d12a12fbca22c98f917c94fdbb73771d6e (diff)
orc.recipe: Add patches needed for UWP support
These are already merged upstream into origin/master, but we need to manually patch these to use the 0.4.31 tarball. Part-of: <https://gitlab.freedesktop.org/gstreamer/cerbero/-/merge_requests/533>
Diffstat (limited to 'recipes/orc')
-rw-r--r--recipes/orc/0001-orc-Implement-a-windows-helper-for-getenv.patch143
-rw-r--r--recipes/orc/0002-orccodemem-Add-support-for-Universal-Windows-Platfor.patch213
-rw-r--r--recipes/orc/0003-orc-Fix-some-warnings-on-MSVC-and-enable-werror.patch75
3 files changed, 431 insertions, 0 deletions
diff --git a/recipes/orc/0001-orc-Implement-a-windows-helper-for-getenv.patch b/recipes/orc/0001-orc-Implement-a-windows-helper-for-getenv.patch
new file mode 100644
index 00000000..984312ba
--- /dev/null
+++ b/recipes/orc/0001-orc-Implement-a-windows-helper-for-getenv.patch
@@ -0,0 +1,143 @@
+From e990f2e17a1eb6c195583db15b25dd1bba88dfa9 Mon Sep 17 00:00:00 2001
+From: Nirbheek Chauhan <nirbheek@centricular.com>
+Date: Tue, 30 Jun 2020 15:30:35 +0530
+Subject: [PATCH 1/4] orc: Implement a windows helper for getenv()
+
+On Windows, getenv() is deprecated and does not work in all cases. On
+the Universal Windows Platform (UWP) it always returns NULL. Add
+a wrapper orc_getenv() that calls GetEnvironmentVariable on Windows.
+
+Also change semantics to always make a copy before returning.
+
+Part-of: <https://gitlab.freedesktop.org/gstreamer/orc/-/merge_requests/42>
+---
+ orc/orc.c | 42 ++++++++++++++++++++++++++++++++++++++++++
+ orc/orccompiler.c | 5 +++--
+ orc/orcdebug.c | 6 ++++--
+ orc/orcinternal.h | 2 ++
+ 4 files changed, 51 insertions(+), 4 deletions(-)
+
+diff --git a/orc/orc.c b/orc/orc.c
+index 2acf522..7b4808c 100644
+--- a/orc/orc.c
++++ b/orc/orc.c
+@@ -5,6 +5,11 @@
+ #include <string.h>
+ #include <stdlib.h>
+
++#ifdef _WIN32
++#include <windows.h>
++#include <processenv.h>
++#endif
++
+ #include <orc/orcprogram.h>
+ #include <orc/orcdebug.h>
+ #include <orc/orconce.h>
+@@ -83,3 +88,40 @@ orc_version_string (void)
+ {
+ return (const char *) VERSION;
+ }
++
++/* getenv() is deprecated on Windows and always returns NULL on UWP */
++#ifdef _WIN32
++char*
++_orc_getenv (const char *key)
++{
++ int len;
++ char check[1], *value;
++
++ /* Get the len */
++ len = GetEnvironmentVariableA (key, check, 1);
++ if (len == 0)
++ /* env var is not set or is "" (empty string) */
++ return NULL;
++
++ /* max size of len is 32767, cannot overflow */
++ value = malloc (sizeof (value) * len);
++
++ if (GetEnvironmentVariableA (key, value, len) != (len - 1)) {
++ free (value);
++ return NULL;
++ }
++
++ return value;
++}
++#else
++char*
++_orc_getenv (const char *key)
++{
++ char *value = getenv (key);
++
++ if (value)
++ value = strdup (value);
++
++ return value;
++}
++#endif
+diff --git a/orc/orccompiler.c b/orc/orccompiler.c
+index 8d92cbe..de2555d 100644
+--- a/orc/orccompiler.c
++++ b/orc/orccompiler.c
+@@ -51,11 +51,12 @@ int _orc_compiler_flag_randomize;
+ void
+ _orc_compiler_init (void)
+ {
+- const char *envvar;
++ char *envvar;
+
+- envvar = getenv ("ORC_CODE");
++ envvar = _orc_getenv ("ORC_CODE");
+ if (envvar != NULL) {
+ _orc_compiler_flag_list = strsplit (envvar, ',');
++ free (envvar);
+ }
+
+ _orc_compiler_flag_backup = orc_compiler_flag_check ("backup");
+diff --git a/orc/orcdebug.c b/orc/orcdebug.c
+index 2e69464..1cefd07 100644
+--- a/orc/orcdebug.c
++++ b/orc/orcdebug.c
+@@ -29,6 +29,7 @@
+ #include "config.h"
+ #endif
+ #include <orc/orcdebug.h>
++#include <orc/orcinternal.h>
+
+ #include <stdio.h>
+ #include <string.h>
+@@ -55,9 +56,9 @@ static OrcDebugPrintFunc _orc_debug_print_func = orc_debug_print_valist;
+ void
+ _orc_debug_init(void)
+ {
+- const char *envvar;
++ char *envvar;
+
+- envvar = getenv ("ORC_DEBUG");
++ envvar = _orc_getenv ("ORC_DEBUG");
+ if (envvar != NULL) {
+ char *end = NULL;
+ int level;
+@@ -65,6 +66,7 @@ _orc_debug_init(void)
+ if (end > envvar) {
+ _orc_debug_level = level;
+ }
++ free (envvar);
+ }
+
+ ORC_INFO ("orc-" VERSION " debug init");
+diff --git a/orc/orcinternal.h b/orc/orcinternal.h
+index cd778c3..b86f698 100644
+--- a/orc/orcinternal.h
++++ b/orc/orcinternal.h
+@@ -36,6 +36,8 @@ extern const char *_orc_cpu_name;
+
+ void orc_compiler_emit_invariants (OrcCompiler *compiler);
+ int orc_program_has_float (OrcCompiler *compiler);
++
++char* _orc_getenv (const char *var);
+ #endif
+
+ ORC_END_DECLS
+--
+2.26.2
+
diff --git a/recipes/orc/0002-orccodemem-Add-support-for-Universal-Windows-Platfor.patch b/recipes/orc/0002-orccodemem-Add-support-for-Universal-Windows-Platfor.patch
new file mode 100644
index 00000000..26174fa2
--- /dev/null
+++ b/recipes/orc/0002-orccodemem-Add-support-for-Universal-Windows-Platfor.patch
@@ -0,0 +1,213 @@
+From cd8eabf041a14b5cdcc13c5436dbccdd66d558bb Mon Sep 17 00:00:00 2001
+From: Nirbheek Chauhan <nirbheek@centricular.com>
+Date: Tue, 30 Jun 2020 16:16:39 +0530
+Subject: [PATCH 2/4] orccodemem: Add support for Universal Windows Platform
+ apps
+
+VirtualAlloc is VirtualAllocFromApp when targeting UWP, and you can
+only allocate executable pages if you have the codeGeneration
+capability set in the app manifest. Check for that capability in
+_orc_compiler_init() and switch to backup code or emulation if it
+isn't available instead of crashing when VirtualAllocFromApp
+returns NULL.
+
+Also you cannot allocate pages that are both READWRITE and EXECUTE, so
+we allocate as read-write first, then set the memory as execute-only
+after the code has been compiled and copied over.
+
+Part-of: <https://gitlab.freedesktop.org/gstreamer/orc/-/merge_requests/42>
+---
+ meson.build | 10 ++++++
+ orc/orccodemem.c | 12 ++++++-
+ orc/orccompiler.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 112 insertions(+), 1 deletion(-)
+
+diff --git a/meson.build b/meson.build
+index c4d955b..eeb3f17 100644
+--- a/meson.build
++++ b/meson.build
+@@ -94,6 +94,16 @@ if host_os == 'windows'
+ cdata.set('HAVE_CODEMEM_VIRTUALALLOC', true)
+ cdata.set('HAVE_OS_WIN32', true)
+ cdata.set('HAVE_THREAD_WIN32', true)
++
++ code = '''
++ #include <windows.h>
++ #if !(WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) && !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP))
++ #error "Not building for UWP"
++ #endif'''
++ if cc.compiles(code, name : 'building for UWP')
++ cdata.set('ORC_WINAPI_ONLY_APP', true)
++ endif
++
+ pc_conf.set('EXEEXT', '.exe')
+ pc_conf.set('PTHREAD_LIBS', '')
+ else
+diff --git a/orc/orccodemem.c b/orc/orccodemem.c
+index 14aadbd..0081835 100644
+--- a/orc/orccodemem.c
++++ b/orc/orccodemem.c
+@@ -11,11 +11,18 @@
+ #include <sys/types.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
++
+ #ifdef HAVE_CODEMEM_MMAP
+ #include <sys/mman.h>
+ #endif
++
+ #ifdef HAVE_CODEMEM_VIRTUALALLOC
+ #include <windows.h>
++ #ifdef ORC_WINAPI_ONLY_APP
++ #define _virtualalloc VirtualAllocFromApp
++ #else
++ #define _virtualalloc VirtualAlloc
++ #endif
+ #endif
+
+ #include <orc/orcinternal.h>
+@@ -299,7 +306,10 @@ orc_code_region_allocate_codemem (OrcCodeRegion *region)
+ void
+ orc_code_region_allocate_codemem (OrcCodeRegion *region)
+ {
+- region->write_ptr = VirtualAlloc(NULL, SIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
++ /* On UWP, we can't allocate memory as executable from the start. We can only
++ * set that later after compiling and copying the code over. This is a good
++ * idea in general to avoid security issues, so we do it on win32 too. */
++ region->write_ptr = _virtualalloc (NULL, SIZE, MEM_COMMIT, PAGE_READWRITE);
+ region->exec_ptr = region->write_ptr;
+ region->size = SIZE;
+ }
+diff --git a/orc/orccompiler.c b/orc/orccompiler.c
+index de2555d..600e66b 100644
+--- a/orc/orccompiler.c
++++ b/orc/orccompiler.c
+@@ -6,6 +6,15 @@
+ #include <stdlib.h>
+ #include <stdarg.h>
+
++#if defined(HAVE_CODEMEM_VIRTUALALLOC)
++#include <windows.h>
++ #ifdef ORC_WINAPI_ONLY_APP
++ #define _virtualprotect VirtualProtectFromApp
++ #else
++ #define _virtualprotect VirtualProtect
++ #endif
++#endif
++
+ #include <orc/orcprogram.h>
+ #include <orc/orcdebug.h>
+ #include <orc/orcinternal.h>
+@@ -63,6 +72,38 @@ _orc_compiler_init (void)
+ _orc_compiler_flag_emulate = orc_compiler_flag_check ("emulate");
+ _orc_compiler_flag_debug = orc_compiler_flag_check ("debug");
+ _orc_compiler_flag_randomize = orc_compiler_flag_check ("randomize");
++
++#if defined(HAVE_CODEMEM_VIRTUALALLOC) && defined(ORC_WINAPI_ONLY_APP)
++ if (!_orc_compiler_flag_backup && !_orc_compiler_flag_emulate) {
++ int can_jit = FALSE;
++ size_t page_size;
++ SYSTEM_INFO info;
++ GetNativeSystemInfo(&info);
++
++ page_size = info.dwPageSize;
++ /* If backup code is not enabled and emulation is not enabled, that means
++ * we will do JIT compilation and call orc_code_region_allocate_codemem().
++ * When targeting Windows Store apps, the codeGeneration capability must
++ * be enabled in the app manifest, or passing PAGE_EXECUTE to
++ * VirtualProtectFromApp will return NULL. In this case, we must force
++ * backup C code, and if that's not available, we must emulate. */
++ void *mem = VirtualAllocFromApp (NULL, page_size, MEM_COMMIT,
++ PAGE_READWRITE);
++ if (mem) {
++ int old_protect;
++ if (VirtualProtectFromApp (mem, page_size, PAGE_EXECUTE, &old_protect) > 0)
++ can_jit = TRUE;
++ VirtualFree (mem, 0, MEM_RELEASE);
++ }
++
++ if (!can_jit) {
++ ORC_WARNING ("Unable to allocate executable pages: using backup code or "
++ "emulation: codeGeneration capability isn't set in the app manifest?");
++ _orc_compiler_flag_backup = TRUE;
++ _orc_compiler_flag_emulate = TRUE;
++ }
++ }
++#endif
+ }
+
+ int
+@@ -175,6 +216,44 @@ orc_program_compile_for_target (OrcProgram *program, OrcTarget *target)
+ return orc_program_compile_full (program, target, flags);
+ }
+
++#if defined(HAVE_CODEMEM_VIRTUALALLOC)
++static const char*
++_get_protect_name (int protect)
++{
++ switch (protect) {
++ /* These are the only two memory protection constants we use */
++ case PAGE_EXECUTE:
++ return "execute";
++ case PAGE_READWRITE:
++ return "readwrite";
++ default:
++ return "unknown";
++ }
++}
++
++static orc_bool
++_set_virtual_protect (void * mem, size_t size, int code_protect)
++{
++ char *msg;
++ DWORD old_protect;
++
++ if (!mem)
++ return FALSE;
++
++ if (_virtualprotect (mem, size, code_protect, &old_protect) > 0)
++ return TRUE;
++
++ FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER
++ | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
++ GetLastError (), 0, (LPTSTR) &msg, 0, NULL);
++ ORC_ERROR ("Couldn't set memory protect on %p from %s to %s: %s", mem,
++ _get_protect_name (old_protect), _get_protect_name (code_protect), msg);
++ LocalFree (msg);
++
++ return FALSE;
++}
++#endif
++
+ /**
+ * orc_program_compile_full:
+ * @program: the OrcProgram to compile
+@@ -360,6 +439,11 @@ orc_program_compile_full (OrcProgram *program, OrcTarget *target,
+ program->orccode->code_size = compiler->codeptr - compiler->code;
+ orc_code_allocate_codemem (program->orccode, program->orccode->code_size);
+
++#if defined(HAVE_CODEMEM_VIRTUALALLOC)
++ /* Ensure that code region is writable before memcpy */
++ _set_virtual_protect (program->orccode->code, program->orccode->code_size,
++ PAGE_READWRITE);
++#endif
+ memcpy (program->orccode->code, compiler->code, program->orccode->code_size);
+
+ #ifdef VALGRIND_DISCARD_TRANSLATIONS
+@@ -371,6 +455,13 @@ orc_program_compile_full (OrcProgram *program, OrcTarget *target,
+ compiler->target->flush_cache (program->orccode);
+ }
+
++#if defined(HAVE_CODEMEM_VIRTUALALLOC)
++ /* Code region is now ready for execution */
++ if (!_set_virtual_protect (program->orccode->exec, program->orccode->code_size,
++ PAGE_EXECUTE))
++ /* Can't set code as executable, force emulation */
++ program->orccode->exec = (void *)orc_executor_emulate;
++#endif
+ program->code_exec = program->orccode->exec;
+
+ program->asm_code = compiler->asm_code;
+--
+2.26.2
+
diff --git a/recipes/orc/0003-orc-Fix-some-warnings-on-MSVC-and-enable-werror.patch b/recipes/orc/0003-orc-Fix-some-warnings-on-MSVC-and-enable-werror.patch
new file mode 100644
index 00000000..2c68fec0
--- /dev/null
+++ b/recipes/orc/0003-orc-Fix-some-warnings-on-MSVC-and-enable-werror.patch
@@ -0,0 +1,75 @@
+From 408e7fa36fbc46e128b680d7b7bf49f694c1aee0 Mon Sep 17 00:00:00 2001
+From: Nirbheek Chauhan <nirbheek@centricular.com>
+Date: Tue, 30 Jun 2020 17:12:54 +0530
+Subject: [PATCH 3/4] orc: Fix some warnings on MSVC and enable --werror
+
+Part-of: <https://gitlab.freedesktop.org/gstreamer/orc/-/merge_requests/42>
+---
+ .gitlab-ci.yml | 4 ++--
+ examples/example2.c | 2 +-
+ orc/orcemulateopcodes.c | 4 ++--
+ testsuite/memcpy_speed.c | 6 +++---
+ 4 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/examples/example2.c b/examples/example2.c
+index c2d03e4..8382771 100644
+--- a/examples/example2.c
++++ b/examples/example2.c
+@@ -21,7 +21,7 @@ main (int argc, char *argv[])
+ }
+
+ /* Call a function that uses Orc */
+- audio_add_mono_to_stereo_scaled_s16 (c, a, b, volume*4096, N);
++ audio_add_mono_to_stereo_scaled_s16 (c, a, b, (int) (volume*4096), N);
+
+ /* Print the results */
+ for(i=0;i<N;i++){
+diff --git a/orc/orcemulateopcodes.c b/orc/orcemulateopcodes.c
+index a0f1aa8..ff09dd2 100644
+--- a/orc/orcemulateopcodes.c
++++ b/orc/orcemulateopcodes.c
+@@ -4896,7 +4896,7 @@ emulate_convlf (OrcOpcodeExecutor *ex, int offset, int n)
+ /* 0: loadl */
+ var32 = ptr4[i];
+ /* 1: convlf */
+- var33.f = var32.i;
++ var33.f = (float) var32.i;
+ /* 2: storel */
+ ptr0[i] = var33;
+ }
+@@ -5279,7 +5279,7 @@ emulate_convdl (OrcOpcodeExecutor *ex, int offset, int n)
+ /* 1: convdl */
+ {
+ int tmp;
+- tmp = var32.f;
++ tmp = (int) var32.f;
+ if (tmp == 0x80000000 && !(var32.i & ORC_UINT64_C(0x8000000000000000))) tmp = 0x7fffffff;
+ var33.i = tmp;
+ }
+diff --git a/testsuite/memcpy_speed.c b/testsuite/memcpy_speed.c
+index 4cf1c39..9f4f247 100644
+--- a/testsuite/memcpy_speed.c
++++ b/testsuite/memcpy_speed.c
+@@ -95,16 +95,16 @@ main(int argc, char *argv[])
+ #endif
+ orc_get_data_cache_sizes (&level1, &level2, &level3);
+ if (level3 > 0) {
+- max = (log(level3)/M_LN2 - 6.0) * 10 + 20;
++ max = (int) ((log(level3)/M_LN2 - 6.0) * 10 + 20);
+ } else if (level2 > 0) {
+- max = (log(level2)/M_LN2 - 6.0) * 10 + 20;
++ max = (int) ((log(level2)/M_LN2 - 6.0) * 10 + 20);
+ } else {
+ max = 140;
+ }
+
+ for(i=0;i<max;i+=2){
+ double x = i*0.1 + 6.0;
+- int size = pow(2.0, x);
++ int size = (int) pow(2.0, x);
+
+ if (size > MAX_SIZE_TO_CHECK) {
+ printf ("Stopping test, exceeding maximum size to check (%d, could do above %d)\n",
+--
+2.26.2
+