PR #22664 opened by Ramiro Polla (ramiro)
URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22664
Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/22664.patch

Only the process functions are entered via an indirect _call_ from C.
The kernel functions and process_return are dispatched to by indirect
_branches_ instead (continuation-passing style design).

Make use of the recently added "jumpable" parameter to the function
macro in libavutil/aarch64/asm.S to fix these functions when BTI is
enabled.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <[email protected]>


>From 1ca8494cfa79bd1f702e9a93d5b78e0d595c5268 Mon Sep 17 00:00:00 2001
From: Ramiro Polla <[email protected]>
Date: Tue, 31 Mar 2026 17:25:12 +0800
Subject: [PATCH 1/2] aarch64: Add support for indirect branch targets in the
 function macro

The function macro emits AARCH64_VALID_CALL_TARGET for exported symbols,
marking them as valid destinations for indirect _calls_. Functions that
are only reached by indirect _branches_ (i.e. tail-call dispatch chains
where the link register is not set) require AARCH64_VALID_JUMP_TARGET
instead.

This commit adds a "jumpable" parameter to the function macro that, when
set, emits AARCH64_VALID_JUMP_TARGET instead of AARCH64_VALID_CALL_TARGET.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <[email protected]>
---
 libavutil/aarch64/asm.S | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libavutil/aarch64/asm.S b/libavutil/aarch64/asm.S
index 00c07058e8..d2f2192e0b 100644
--- a/libavutil/aarch64/asm.S
+++ b/libavutil/aarch64/asm.S
@@ -256,7 +256,7 @@ DISABLE_SME2
         .popsection
 #endif
 
-.macro  function name, export=0, align=4
+.macro  function name, export=0, jumpable=0, align=4
     .macro endfunc
 ELF     .size   \name, . - \name
 FUNC    .endfunc
@@ -269,7 +269,11 @@ FUNC    .endfunc
 ELF     .type   EXTERN_ASM\name, %function
 FUNC    .func   EXTERN_ASM\name
 EXTERN_ASM\name:
+    .if \jumpable
+        AARCH64_VALID_JUMP_TARGET
+    .else
         AARCH64_VALID_CALL_TARGET
+    .endif
     .else
 ELF     .type   \name, %function
 FUNC    .func   \name
-- 
2.52.0


>From 5d790e45ed8f86cc14cef291562749940929fae5 Mon Sep 17 00:00:00 2001
From: Ramiro Polla <[email protected]>
Date: Tue, 31 Mar 2026 17:33:28 +0800
Subject: [PATCH 2/2] swscale/aarch64: mark CPS kernel functions as indirect
 branch targets

Only the process functions are entered via an indirect _call_ from C.
The kernel functions and process_return are dispatched to by indirect
_branches_ instead (continuation-passing style design).

Make use of the recently added "jumpable" parameter to the function
macro in libavutil/aarch64/asm.S to fix these functions when BTI is
enabled.

Sponsored-by: Sovereign Tech Fund
Signed-off-by: Ramiro Polla <[email protected]>
---
 libswscale/aarch64/ops_asmgen.c |  6 +++---
 libswscale/aarch64/rasm.c       | 13 ++++++++-----
 libswscale/aarch64/rasm.h       |  7 +++++--
 libswscale/aarch64/rasm_print.c |  3 ++-
 4 files changed, 18 insertions(+), 11 deletions(-)

diff --git a/libswscale/aarch64/ops_asmgen.c b/libswscale/aarch64/ops_asmgen.c
index 1ec7fc7b5e..626ce00e5e 100644
--- a/libswscale/aarch64/ops_asmgen.c
+++ b/libswscale/aarch64/ops_asmgen.c
@@ -298,7 +298,7 @@ static void asmgen_process(SwsAArch64Context *s, const 
SwsAArch64OpImplParams *p
 
     aarch64_op_impl_func_name(func_name, sizeof(func_name), p);
 
-    rasm_func_begin(r, func_name, true);
+    rasm_func_begin(r, func_name, true, false);
 
     /* Function prologue */
     RasmOp saved_regs[MAX_SAVED_REGS];
@@ -341,7 +341,7 @@ static void asmgen_process_return(SwsAArch64Context *s, 
const SwsAArch64OpImplPa
 
     aarch64_op_impl_func_name(func_name, sizeof(func_name), p);
 
-    rasm_func_begin(r, func_name, true);
+    rasm_func_begin(r, func_name, true, true);
 
     /* Reset impl to first kernel. */
     i_mov(r, s->impl, s->op1_impl);         CMT("impl = op1_impl;");
@@ -1348,7 +1348,7 @@ static void asmgen_op_cps(SwsAArch64Context *s, const 
SwsAArch64OpImplParams *p)
 
     char func_name[128];
     aarch64_op_impl_func_name(func_name, sizeof(func_name), p);
-    rasm_func_begin(r, func_name, true);
+    rasm_func_begin(r, func_name, true, true);
 
     /**
      * Set up vector register dimensions and reshape all vectors
diff --git a/libswscale/aarch64/rasm.c b/libswscale/aarch64/rasm.c
index 2428c345e2..abea0e8dce 100644
--- a/libswscale/aarch64/rasm.c
+++ b/libswscale/aarch64/rasm.c
@@ -152,13 +152,15 @@ RasmNode *rasm_add_label(RasmContext *rctx, int id)
     return node;
 }
 
-RasmNode *rasm_add_func(RasmContext *rctx, int id, bool export)
+RasmNode *rasm_add_func(RasmContext *rctx, int id, bool export,
+                        bool jumpable)
 {
     RasmNode *node = add_node(rctx, RASM_NODE_FUNCTION);
     if (node) {
         av_assert0(id >= 0 && id < rctx->num_labels);
-        node->func.name   = rctx->labels[id];
-        node->func.export = export;
+        node->func.name     = rctx->labels[id];
+        node->func.export   = export;
+        node->func.jumpable = jumpable;
     }
     return node;
 }
@@ -204,7 +206,8 @@ RasmNode *rasm_set_current_node(RasmContext *rctx, RasmNode 
*node)
 /*********************************************************************/
 /* Top-level IR entries */
 
-int rasm_func_begin(RasmContext *rctx, const char *name, bool export)
+int rasm_func_begin(RasmContext *rctx, const char *name, bool export,
+                    bool jumpable)
 {
     if (rctx->error)
         return rctx->error;
@@ -223,7 +226,7 @@ int rasm_func_begin(RasmContext *rctx, const char *name, 
bool export)
     int id = rasm_new_label(rctx, name);
 
     rasm_set_current_node(rctx, NULL);
-    entry->start = rasm_add_func(rctx, id, export);
+    entry->start = rasm_add_func(rctx, id, export, jumpable);
     entry->end   = rasm_add_endfunc(rctx);
     rasm_set_current_node(rctx, entry->start);
 
diff --git a/libswscale/aarch64/rasm.h b/libswscale/aarch64/rasm.h
index b7ba87e26a..5a14d8cd64 100644
--- a/libswscale/aarch64/rasm.h
+++ b/libswscale/aarch64/rasm.h
@@ -133,6 +133,7 @@ typedef struct RasmNodeLabel {
 typedef struct RasmNodeFunc {
     char *name;
     bool export;
+    bool jumpable;
 } RasmNodeFunc;
 
 typedef struct RasmNodeDirective {
@@ -200,7 +201,8 @@ RasmNode *rasm_add_comment(RasmContext *rctx, const char 
*comment);
 RasmNode *rasm_add_commentf(RasmContext *rctx, char *s, size_t n,
                             const char *fmt, ...) av_printf_format(4, 5);
 RasmNode *rasm_add_label(RasmContext *rctx, int id);
-RasmNode *rasm_add_func(RasmContext *rctx, int id, bool export);
+RasmNode *rasm_add_func(RasmContext *rctx, int id, bool export,
+                        bool jumpable);
 RasmNode *rasm_add_endfunc(RasmContext *rctx);
 RasmNode *rasm_add_directive(RasmContext *rctx, const char *text);
 
@@ -208,7 +210,8 @@ RasmNode *rasm_get_current_node(RasmContext *rctx);
 RasmNode *rasm_set_current_node(RasmContext *rctx, RasmNode *node);
 
 /* Top-level IR entries */
-int rasm_func_begin(RasmContext *rctx, const char *name, bool export);
+int rasm_func_begin(RasmContext *rctx, const char *name, bool export,
+                    bool jumpable);
 
 /**
  * Allocate a new label ID with the given name.
diff --git a/libswscale/aarch64/rasm_print.c b/libswscale/aarch64/rasm_print.c
index 31e03da084..86f543b3c9 100644
--- a/libswscale/aarch64/rasm_print.c
+++ b/libswscale/aarch64/rasm_print.c
@@ -402,7 +402,8 @@ static void print_node_function(const RasmContext *rctx,
                                 FILE *fp, int64_t *pos, int64_t line_start,
                                 const RasmNode *node)
 {
-    pos_fprintf(fp, pos, "function %s, export=%d", node->func.name, 
node->func.export);
+    pos_fprintf(fp, pos, "function %s, export=%d, jumpable=%d",
+                node->func.name, node->func.export, node->func.jumpable);
 }
 
 /*********************************************************************/
-- 
2.52.0

_______________________________________________
ffmpeg-devel mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to