ldelf: support TA ftrace
Adds support in ldelf to dump ftrace data.
Reviewed-by: Sumit Garg <sumit.garg@linaro.org>
Acked-by: Jerome Forissier <jerome.forissier@linaro.org>
Signed-off-by: Jens Wiklander <jens.wiklander@linaro.org>
diff --git a/ldelf/main.c b/ldelf/main.c
index d512847..ecc07ad 100644
--- a/ldelf/main.c
+++ b/ldelf/main.c
@@ -6,17 +6,27 @@
#include <assert.h>
#include <ldelf.h>
#include <malloc.h>
+#include <printk.h>
+#include <string.h>
#include <sys/queue.h>
#include <tee_api_types.h>
#include <trace.h>
#include <types_ext.h>
+#include <util.h>
-#include "ta_elf.h"
+#include "ftrace.h"
#include "sys.h"
+#include "ta_elf.h"
static size_t mpool_size = 2 * SMALL_PAGE_SIZE;
static vaddr_t mpool_base;
+static void __printf(2, 0) print_to_console(void *pctx __unused,
+ const char *fmt, va_list ap)
+{
+ trace_vprintf(NULL, 0, TRACE_ERROR, true, fmt, ap);
+}
+
static void __noreturn __maybe_unused dump_ta_state(struct dump_entry_arg *arg)
{
struct ta_elf *elf = TAILQ_FIRST(&main_elf_queue);
@@ -26,8 +36,8 @@
EMSG_RAW(" arch: %s", elf->is_32bit ? "arm" : "aarch64");
- ta_elf_print_mappings(&main_elf_queue, arg->num_maps, arg->maps,
- mpool_base);
+ ta_elf_print_mappings(NULL, print_to_console, &main_elf_queue,
+ arg->num_maps, arg->maps, mpool_base);
if (arg->is_arm32)
ta_elf_stack_trace_a32(arg->arm32.regs);
@@ -38,6 +48,60 @@
sys_return_cleanup();
}
+#ifdef CFG_TA_FTRACE_SUPPORT
+struct print_buf_ctx {
+ char *buf;
+ size_t blen;
+ size_t ret;
+};
+
+static void __printf(2, 0) print_to_pbuf(void *pctx, const char *fmt,
+ va_list ap)
+{
+ struct print_buf_ctx *pbuf = pctx;
+ char *buf = NULL;
+ size_t blen = 0;
+ int ret = 0;
+
+ if (pbuf->buf && pbuf->blen > pbuf->ret) {
+ buf = pbuf->buf + pbuf->ret;
+ blen = pbuf->blen - pbuf->ret;
+ }
+
+ ret = vsnprintk(buf, blen, fmt, ap);
+ assert(ret >= 0);
+
+ pbuf->ret += ret;
+}
+
+static void copy_to_pbuf(void *pctx, void *b, size_t bl)
+{
+ struct print_buf_ctx *pbuf = pctx;
+ char *buf = NULL;
+ size_t blen = 0;
+
+ if (pbuf->buf && pbuf->blen > pbuf->ret) {
+ buf = pbuf->buf + pbuf->ret;
+ blen = pbuf->blen - pbuf->ret;
+ memcpy(buf, b, MIN(blen, bl));
+ }
+
+ pbuf->ret += bl;
+
+}
+
+static void __noreturn ftrace_dump(void *buf, size_t *blen)
+{
+ struct print_buf_ctx pbuf = { .buf = buf, .blen = *blen };
+
+ ta_elf_print_mappings(&pbuf, print_to_pbuf, &main_elf_queue,
+ 0, NULL, mpool_base);
+ ftrace_copy_buf(&pbuf, copy_to_pbuf);
+ *blen = pbuf.ret;
+ sys_return_cleanup();
+}
+#endif
+
/*
* ldelf()- Loads ELF into memory
* @arg: Argument passing to/from TEE Core
@@ -75,6 +139,12 @@
ta_elf_finalize_mappings(elf);
}
+ arg->ftrace_entry = 0;
+#ifdef CFG_TA_FTRACE_SUPPORT
+ if (ftrace_init())
+ arg->ftrace_entry = (vaddr_t)(void *)ftrace_dump;
+#endif
+
TAILQ_FOREACH(elf, &main_elf_queue, link)
DMSG("ELF (%pUl) at %#"PRIxVA,
(void *)&elf->uuid, elf->load_addr);