From 80f91558a173fe841810ab6a7a0f70b52344ec76 Mon Sep 17 00:00:00 2001
From: Simon Glass <sjg@chromium.org>
Date: Sun, 15 Jan 2023 14:15:50 -0700
Subject: [PATCH] trace: Correct the relocation handover with buffer overflow

When the early trace buffer overflows it leaves a gap in the trace buffer
between where the actual data finished and where it would have finished if
there were enough buffer space. This results in corrupted output.

Adjust the logic to resolve this and add a message when the buffer
overflows.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
 lib/trace.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/lib/trace.c b/lib/trace.c
index c3354a256f..bbc316af29 100644
--- a/lib/trace.c
+++ b/lib/trace.c
@@ -360,8 +360,8 @@ int notrace trace_init(void *buff, size_t buff_size)
 
 	if (!was_disabled) {
 #ifdef CONFIG_TRACE_EARLY
+		ulong used, count;
 		char *end;
-		ulong used;
 
 		/*
 		 * Copy over the early trace data if we have it. Disable
@@ -370,12 +370,19 @@ int notrace trace_init(void *buff, size_t buff_size)
 		trace_enabled = 0;
 		hdr = map_sysmem(CONFIG_TRACE_EARLY_ADDR,
 				 CONFIG_TRACE_EARLY_SIZE);
-		end = (char *)&hdr->ftrace[min(hdr->ftrace_count,
-					       hdr->ftrace_size)];
+		count = min(hdr->ftrace_count, hdr->ftrace_size);
+		end = (char *)&hdr->ftrace[count];
 		used = end - (char *)hdr;
 		printf("trace: copying %08lx bytes of early data from %x to %08lx\n",
 		       used, CONFIG_TRACE_EARLY_ADDR,
 		       (ulong)map_to_sysmem(buff));
+		printf("%lu traced function calls", count);
+		if (hdr->ftrace_count > hdr->ftrace_size) {
+			printf(" (%lu dropped due to overflow)",
+			       hdr->ftrace_count - hdr->ftrace_size);
+			hdr->ftrace_count = hdr->ftrace_size;
+		}
+		puts("\n");
 		memcpy(buff, hdr, used);
 #else
 		puts("trace: already enabled\n");
-- 
2.39.5