diff mbox series

[1/3] ftrace: initial support for 32 bit apps

Message ID 1557225797-32604-1-git-send-email-sumit.garg@linaro.org
State New
Headers show
Series [1/3] ftrace: initial support for 32 bit apps | expand

Commit Message

Sumit Garg May 7, 2019, 10:43 a.m. UTC
Signed-off-by: Sumit Garg <sumit.garg@linaro.org>

---
 core/arch/arm/arm.mk                   | 18 +++++++++++++++---
 core/arch/arm/kernel/ftrace.c          |  7 ++++---
 lib/libutee/arch/arm/utee_mcount_a32.S | 27 +++++++++++++++++++--------
 lib/libutee/include/user_ta_header.h   | 10 +++++-----
 ta/arch/arm/user_ta_header.c           |  9 +++++++--
 5 files changed, 50 insertions(+), 21 deletions(-)

-- 
2.7.4

Comments

Sumit Garg May 7, 2019, 10:51 a.m. UTC | #1
# Note that this patch is in sequence after
https://github.com/OP-TEE/optee_os/pull/2912.

On Tue, 7 May 2019 at 16:13, Sumit Garg <sumit.garg@linaro.org> wrote:
>

> Signed-off-by: Sumit Garg <sumit.garg@linaro.org>

> ---

>  core/arch/arm/arm.mk                   | 18 +++++++++++++++---

>  core/arch/arm/kernel/ftrace.c          |  7 ++++---

>  lib/libutee/arch/arm/utee_mcount_a32.S | 27 +++++++++++++++++++--------

>  lib/libutee/include/user_ta_header.h   | 10 +++++-----

>  ta/arch/arm/user_ta_header.c           |  9 +++++++--

>  5 files changed, 50 insertions(+), 21 deletions(-)

>

> diff --git a/core/arch/arm/arm.mk b/core/arch/arm/arm.mk

> index be53df2..f03bf6c 100644

> --- a/core/arch/arm/arm.mk

> +++ b/core/arch/arm/arm.mk

> @@ -89,7 +89,9 @@ platform-aflags-generic ?= -pipe

>

>  arm32-platform-cflags-no-hard-float ?= -mfloat-abi=soft

>  arm32-platform-cflags-hard-float ?= -mfloat-abi=hard -funsafe-math-optimizations

> -arm32-platform-cflags-generic ?= -mthumb -mthumb-interwork \

> +arm32-platform-cflags-generic-thumb ?= -mthumb -mthumb-interwork \

> +                       -fno-short-enums -fno-common -mno-unaligned-access

> +arm32-platform-cflags-generic-arm ?= -marm \

>                         -fno-short-enums -fno-common -mno-unaligned-access

>  arm32-platform-aflags-no-hard-float ?=

>

> @@ -138,7 +140,7 @@ core-platform-cflags += $(arm32-platform-cflags-no-hard-float)

>  ifeq ($(CFG_UNWIND),y)

>  core-platform-cflags += -funwind-tables

>  endif

> -core-platform-cflags += $(arm32-platform-cflags-generic)

> +core-platform-cflags += $(arm32-platform-cflags-generic-thumb)

>  core-platform-aflags += $(core_arm32-platform-aflags)

>  core-platform-aflags += $(arm32-platform-aflags)

>  endif

> @@ -166,7 +168,17 @@ ta_arm32-platform-cflags += $(arm32-platform-cflags)

>  ta_arm32-platform-cflags += $(platform-cflags-optimization)

>  ta_arm32-platform-cflags += $(platform-cflags-debug-info)

>  ta_arm32-platform-cflags += -fpic

> -ta_arm32-platform-cflags += $(arm32-platform-cflags-generic)

> +

> +# Thumb mode doesn't support function graph tracing due to missing

> +# frame pointer support required to trace function call chain. So

> +# rather compile in ARM mode if function tracing is enabled.

> +ifeq ($(CFG_TA_FTRACE_SUPPORT),y)

> +ta_arm32-platform-cflags += $(arm32-platform-cflags-generic-arm) \

> +                       -fno-omit-frame-pointer -mapcs

> +else

> +ta_arm32-platform-cflags += $(arm32-platform-cflags-generic-thumb)

> +endif

> +

>  ifeq ($(arm32-platform-hard-float-enabled),y)

>  ta_arm32-platform-cflags += $(arm32-platform-cflags-hard-float)

>  else

> diff --git a/core/arch/arm/kernel/ftrace.c b/core/arch/arm/kernel/ftrace.c

> index 4b4a49b..8f34c6a 100644

> --- a/core/arch/arm/kernel/ftrace.c

> +++ b/core/arch/arm/kernel/ftrace.c

> @@ -23,11 +23,12 @@ void ta_fbuf_init(struct ta_head *ta_head, struct tee_ta_session *s)

>         size_t fbuf_size = 0;

>         int count = 0;

>

> -       if (ta_head->ftrace_buf_end > ta_head->ftrace_buf_start)

> -               fbuf_size = ta_head->ftrace_buf_end - ta_head->ftrace_buf_start;

> +       if (ta_head->ftrace_buf_end.ptr64 > ta_head->ftrace_buf_start.ptr64)

> +               fbuf_size = ta_head->ftrace_buf_end.ptr64 -

> +                                ta_head->ftrace_buf_start.ptr64;

>

>         if (fbuf_size >= MIN_FTRACE_BUF_SIZE) {

> -               fbuf = (struct ftrace_buf *)ta_head->ftrace_buf_start;

> +               fbuf = (struct ftrace_buf *)ta_head->ftrace_buf_start.ptr64;

>                 fbuf->head_off = sizeof(struct ftrace_buf);

>                 count = snprintk((char *)fbuf + fbuf->head_off,

>                                  MAX_HEADER_STRLEN,

> diff --git a/lib/libutee/arch/arm/utee_mcount_a32.S b/lib/libutee/arch/arm/utee_mcount_a32.S

> index 0626baa..8923b8a 100644

> --- a/lib/libutee/arch/arm/utee_mcount_a32.S

> +++ b/lib/libutee/arch/arm/utee_mcount_a32.S

> @@ -26,25 +26,36 @@

>   */

>  FUNC __gnu_mcount_nc, :

>         stmdb           sp!, {r0-r3, lr}

> -       ldr             r0, [sp, #20]           /* lr of instrumented func */

>  #ifdef CFG_TA_GPROF_SUPPORT

> +       ldr             r0, [sp, #20]           /* lr of instrumented func */

>         mcount_adj_pc   r0, r0

>         mcount_adj_pc   r1, lr                  /* instrumented func */

>         bl              __mcount_internal

>  #endif

> +#ifdef CFG_TA_FTRACE_SUPPORT

> +       /* Get instrumented function's pc value */

> +       ldr             r0, [sp, #16]

> +       mcount_adj_pc   r0, r0

> +       /* Get instrumented function's lr address pointer */

> +       sub             r1, fp, #4


Here the frame pointer is used to fetch instrumented function's lr
address pointer. ftrace_enter api would save original lr in the stack
and modify lr to point to __ftrace_return api.

> +       bl              ftrace_enter

> +#endif

>         ldmia           sp!, {r0-r3, ip, lr}

>         bx              ip

>  END_FUNC __gnu_mcount_nc

>

>  #ifdef CFG_TA_FTRACE_SUPPORT

> -/*

> - * ftrace is not yet supported in 32bit mode. Currently this is just a

> - * placeholder to avoid linking error.

> - */

>  FUNC __ftrace_return, :

> -       push            {lr}

> -       pop             {ip, lr}

> -       bx              ip

> +       /* save return value regs */

> +       stmdb           sp!, {r0-r3}

> +

> +       /* get return address of parent func */

> +       bl              ftrace_return

> +       mov             lr, r0


Here ftrace_return dumps the exit point of instrumented function and
fetches original lr from the stack to return to parent of instrumented
function.

-Sumit

> +

> +       /* restore return value regs */

> +       ldmia           sp!, {r0-r3}

> +       bx              lr

>  END_FUNC __ftrace_return

>  #endif

>

> diff --git a/lib/libutee/include/user_ta_header.h b/lib/libutee/include/user_ta_header.h

> index e2445b2..63e5d82 100644

> --- a/lib/libutee/include/user_ta_header.h

> +++ b/lib/libutee/include/user_ta_header.h

> @@ -27,9 +27,9 @@

>

>  #define TA_FLAGS_MASK                  GENMASK_32(9, 0)

>

> -union ta_head_func_ptr {

> +union compat_ptr {

>         uint64_t ptr64;

> -       struct ta_head_func_ptr32 {

> +       struct compat_ptr32 {

>                 uint32_t lo;

>                 uint32_t hi;

>         } ptr32;

> @@ -39,10 +39,10 @@ struct ta_head {

>         TEE_UUID uuid;

>         uint32_t stack_size;

>         uint32_t flags;

> -       union ta_head_func_ptr entry;

> +       union compat_ptr entry;

>  #ifdef CFG_TA_FTRACE_SUPPORT

> -       uintptr_t ftrace_buf_start;

> -       uintptr_t ftrace_buf_end;

> +       union compat_ptr ftrace_buf_start;

> +       union compat_ptr ftrace_buf_end;

>  #endif

>  };

>

> diff --git a/ta/arch/arm/user_ta_header.c b/ta/arch/arm/user_ta_header.c

> index 5496294..d294f1f 100644

> --- a/ta/arch/arm/user_ta_header.c

> +++ b/ta/arch/arm/user_ta_header.c

> @@ -60,8 +60,13 @@ const struct ta_head ta_head __section(".ta_head") = {

>         .entry.ptr64 = (uint64_t)__utee_entry,

>  #endif

>  #ifdef CFG_TA_FTRACE_SUPPORT

> -       .ftrace_buf_start = (uintptr_t)&__ftrace_buf_start,

> -       .ftrace_buf_end = (uintptr_t)__ftrace_buf_end,

> +#ifdef __ILP32__

> +       .ftrace_buf_start.ptr32 = { .lo = (uint32_t)&__ftrace_buf_start },

> +       .ftrace_buf_end.ptr32 = { .lo = (uint32_t)__ftrace_buf_end },

> +#else

> +       .ftrace_buf_start.ptr64 = (uint64_t)&__ftrace_buf_start,

> +       .ftrace_buf_end.ptr64 = (uint64_t)__ftrace_buf_end,

> +#endif

>  #endif

>  };

>

> --

> 2.7.4

>
diff mbox series

Patch

diff --git a/core/arch/arm/arm.mk b/core/arch/arm/arm.mk
index be53df2..f03bf6c 100644
--- a/core/arch/arm/arm.mk
+++ b/core/arch/arm/arm.mk
@@ -89,7 +89,9 @@  platform-aflags-generic ?= -pipe
 
 arm32-platform-cflags-no-hard-float ?= -mfloat-abi=soft
 arm32-platform-cflags-hard-float ?= -mfloat-abi=hard -funsafe-math-optimizations
-arm32-platform-cflags-generic ?= -mthumb -mthumb-interwork \
+arm32-platform-cflags-generic-thumb ?= -mthumb -mthumb-interwork \
+			-fno-short-enums -fno-common -mno-unaligned-access
+arm32-platform-cflags-generic-arm ?= -marm \
 			-fno-short-enums -fno-common -mno-unaligned-access
 arm32-platform-aflags-no-hard-float ?=
 
@@ -138,7 +140,7 @@  core-platform-cflags += $(arm32-platform-cflags-no-hard-float)
 ifeq ($(CFG_UNWIND),y)
 core-platform-cflags += -funwind-tables
 endif
-core-platform-cflags += $(arm32-platform-cflags-generic)
+core-platform-cflags += $(arm32-platform-cflags-generic-thumb)
 core-platform-aflags += $(core_arm32-platform-aflags)
 core-platform-aflags += $(arm32-platform-aflags)
 endif
@@ -166,7 +168,17 @@  ta_arm32-platform-cflags += $(arm32-platform-cflags)
 ta_arm32-platform-cflags += $(platform-cflags-optimization)
 ta_arm32-platform-cflags += $(platform-cflags-debug-info)
 ta_arm32-platform-cflags += -fpic
-ta_arm32-platform-cflags += $(arm32-platform-cflags-generic)
+
+# Thumb mode doesn't support function graph tracing due to missing
+# frame pointer support required to trace function call chain. So
+# rather compile in ARM mode if function tracing is enabled.
+ifeq ($(CFG_TA_FTRACE_SUPPORT),y)
+ta_arm32-platform-cflags += $(arm32-platform-cflags-generic-arm) \
+			-fno-omit-frame-pointer -mapcs
+else
+ta_arm32-platform-cflags += $(arm32-platform-cflags-generic-thumb)
+endif
+
 ifeq ($(arm32-platform-hard-float-enabled),y)
 ta_arm32-platform-cflags += $(arm32-platform-cflags-hard-float)
 else
diff --git a/core/arch/arm/kernel/ftrace.c b/core/arch/arm/kernel/ftrace.c
index 4b4a49b..8f34c6a 100644
--- a/core/arch/arm/kernel/ftrace.c
+++ b/core/arch/arm/kernel/ftrace.c
@@ -23,11 +23,12 @@  void ta_fbuf_init(struct ta_head *ta_head, struct tee_ta_session *s)
 	size_t fbuf_size = 0;
 	int count = 0;
 
-	if (ta_head->ftrace_buf_end > ta_head->ftrace_buf_start)
-		fbuf_size = ta_head->ftrace_buf_end - ta_head->ftrace_buf_start;
+	if (ta_head->ftrace_buf_end.ptr64 > ta_head->ftrace_buf_start.ptr64)
+		fbuf_size = ta_head->ftrace_buf_end.ptr64 -
+				 ta_head->ftrace_buf_start.ptr64;
 
 	if (fbuf_size >= MIN_FTRACE_BUF_SIZE) {
-		fbuf = (struct ftrace_buf *)ta_head->ftrace_buf_start;
+		fbuf = (struct ftrace_buf *)ta_head->ftrace_buf_start.ptr64;
 		fbuf->head_off = sizeof(struct ftrace_buf);
 		count = snprintk((char *)fbuf + fbuf->head_off,
 				 MAX_HEADER_STRLEN,
diff --git a/lib/libutee/arch/arm/utee_mcount_a32.S b/lib/libutee/arch/arm/utee_mcount_a32.S
index 0626baa..8923b8a 100644
--- a/lib/libutee/arch/arm/utee_mcount_a32.S
+++ b/lib/libutee/arch/arm/utee_mcount_a32.S
@@ -26,25 +26,36 @@ 
  */
 FUNC __gnu_mcount_nc, :
 	stmdb		sp!, {r0-r3, lr}
-	ldr		r0, [sp, #20]		/* lr of instrumented func */
 #ifdef CFG_TA_GPROF_SUPPORT
+	ldr		r0, [sp, #20]		/* lr of instrumented func */
 	mcount_adj_pc	r0, r0
 	mcount_adj_pc	r1, lr			/* instrumented func */
 	bl		__mcount_internal
 #endif
+#ifdef CFG_TA_FTRACE_SUPPORT
+	/* Get instrumented function's pc value */
+	ldr		r0, [sp, #16]
+	mcount_adj_pc	r0, r0
+	/* Get instrumented function's lr address pointer */
+	sub		r1, fp, #4
+	bl		ftrace_enter
+#endif
 	ldmia		sp!, {r0-r3, ip, lr}
 	bx		ip
 END_FUNC __gnu_mcount_nc
 
 #ifdef CFG_TA_FTRACE_SUPPORT
-/*
- * ftrace is not yet supported in 32bit mode. Currently this is just a
- * placeholder to avoid linking error.
- */
 FUNC __ftrace_return, :
-	push		{lr}
-	pop		{ip, lr}
-	bx		ip
+	/* save return value regs */
+	stmdb		sp!, {r0-r3}
+
+	/* get return address of parent func */
+	bl		ftrace_return
+	mov		lr, r0
+
+	/* restore return value regs */
+	ldmia		sp!, {r0-r3}
+	bx		lr
 END_FUNC __ftrace_return
 #endif
 
diff --git a/lib/libutee/include/user_ta_header.h b/lib/libutee/include/user_ta_header.h
index e2445b2..63e5d82 100644
--- a/lib/libutee/include/user_ta_header.h
+++ b/lib/libutee/include/user_ta_header.h
@@ -27,9 +27,9 @@ 
 
 #define TA_FLAGS_MASK			GENMASK_32(9, 0)
 
-union ta_head_func_ptr {
+union compat_ptr {
 	uint64_t ptr64;
-	struct ta_head_func_ptr32 {
+	struct compat_ptr32 {
 		uint32_t lo;
 		uint32_t hi;
 	} ptr32;
@@ -39,10 +39,10 @@  struct ta_head {
 	TEE_UUID uuid;
 	uint32_t stack_size;
 	uint32_t flags;
-	union ta_head_func_ptr entry;
+	union compat_ptr entry;
 #ifdef CFG_TA_FTRACE_SUPPORT
-	uintptr_t ftrace_buf_start;
-	uintptr_t ftrace_buf_end;
+	union compat_ptr ftrace_buf_start;
+	union compat_ptr ftrace_buf_end;
 #endif
 };
 
diff --git a/ta/arch/arm/user_ta_header.c b/ta/arch/arm/user_ta_header.c
index 5496294..d294f1f 100644
--- a/ta/arch/arm/user_ta_header.c
+++ b/ta/arch/arm/user_ta_header.c
@@ -60,8 +60,13 @@  const struct ta_head ta_head __section(".ta_head") = {
 	.entry.ptr64 = (uint64_t)__utee_entry,
 #endif
 #ifdef CFG_TA_FTRACE_SUPPORT
-	.ftrace_buf_start = (uintptr_t)&__ftrace_buf_start,
-	.ftrace_buf_end = (uintptr_t)__ftrace_buf_end,
+#ifdef __ILP32__
+	.ftrace_buf_start.ptr32 = { .lo = (uint32_t)&__ftrace_buf_start },
+	.ftrace_buf_end.ptr32 = { .lo = (uint32_t)__ftrace_buf_end },
+#else
+	.ftrace_buf_start.ptr64 = (uint64_t)&__ftrace_buf_start,
+	.ftrace_buf_end.ptr64 = (uint64_t)__ftrace_buf_end,
+#endif
 #endif
 };