diff options
author | L. E. Segovia <amy@centricular.com> | 2024-08-07 13:05:26 +0000 |
---|---|---|
committer | GStreamer Marge Bot <gitlab-merge-bot@gstreamer-foundation.org> | 2024-08-08 14:01:35 +0000 |
commit | be893adcd8b6ce49a64b626716a652903ab728ee (patch) | |
tree | 5d1735c8b3c8f57e686d2401d60d4413ba1d1212 | |
parent | bd57083978608067a92eb20b7c8d00658ca29fa0 (diff) |
x86: handle unnatural and misaligned array pointers
At least on Linux, it is possible to make Orc crash by supplying an array
parameter whose alignment doesn't match the variable size; this is not the
element size, but rather the total number of elements (the second parameter of
`.dest`).
We've decided to preserve the default alignment to the parameter size, and so
the crash when an user supplies a misaligned pointer, but if a parameter is
explicitly specified to be misaligned (e.g. `.dest 4 x align 2 int16_t`)
let's convert all accesses to unaligned.
Fixes #72
Part-of: <https://gitlab.freedesktop.org/gstreamer/orc/-/merge_requests/200>
-rw-r--r-- | orc/orcprogram-x86.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/orc/orcprogram-x86.c b/orc/orcprogram-x86.c index 9e7242f..b0f2962 100644 --- a/orc/orcprogram-x86.c +++ b/orc/orcprogram-x86.c @@ -442,6 +442,20 @@ orc_x86_get_shift (OrcX86Target *t, int size) return t->get_shift(size); } +static inline orc_bool +has_valid_alignment (const OrcVariable *var) +{ + return (var->alignment % var->size) == 0; +} + +static inline orc_bool +can_be_validly_aligned (const OrcVariable *var, const OrcX86Target *t) +{ + const orc_bool alignment_matches_register = + (var->alignment % t->register_size) == 0; + return alignment_matches_register && has_valid_alignment (var); +} + static void orc_x86_emit_split_3_regions (OrcX86Target *t, OrcCompiler *compiler) { @@ -795,7 +809,7 @@ orc_x86_adjust_alignment (OrcX86Target *t, OrcCompiler *compiler) for (i = ORC_VAR_D1; i <= ORC_VAR_S8; i++) { if (compiler->vars[i].size == 0) continue; - if ((compiler->vars[i].alignment % t->register_size) == 0) { + if (can_be_validly_aligned (&compiler->vars[i], t)) { compiler->vars[i].is_aligned = TRUE; } else { compiler->vars[i].is_aligned = FALSE; @@ -950,7 +964,8 @@ orc_x86_compile (OrcCompiler *compiler) } compiler->loop_shift = save_loop_shift; - compiler->vars[align_var].is_aligned = TRUE; + /* Consider as aligned only if the alignment allows so */ + compiler->vars[align_var].is_aligned = has_valid_alignment (&compiler->vars[align_var]); } orc_x86_emit_label (compiler, LABEL_REGION1_SKIP); |