git: b80a1b584f26 - stable/13 - MFC: Add TSLOG to loader sprintf

From: Colin Percival <cperciva_at_FreeBSD.org>
Date: Wed, 29 Dec 2021 23:06:27 UTC
The branch stable/13 has been updated by cperciva:

URL: https://cgit.FreeBSD.org/src/commit/?id=b80a1b584f2676d4a75aa669f34a8982578408bf

commit b80a1b584f2676d4a75aa669f34a8982578408bf
Author:     Colin Percival <cperciva@FreeBSD.org>
AuthorDate: 2021-09-25 03:19:38 +0000
Commit:     Colin Percival <cperciva@FreeBSD.org>
CommitDate: 2021-12-29 22:53:19 +0000

    MFC: Add TSLOG to loader sprintf
    
    loader tslog: Don't use sprintf
    loader printf: Profile with TSLOG
    
    Sponsored by:   https://www.patreon.com/cperciva
    
    (cherry picked from commit 242923eb848a94d657344c2ff45c4f15433cdf3c)
    (cherry picked from commit 0a35c4b3cab563e3ab1bf5b7b49bf26e0bb7cb04)
---
 stand/libsa/printf.c |  5 ++++-
 stand/libsa/tslog.c  | 50 +++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 47 insertions(+), 8 deletions(-)

diff --git a/stand/libsa/printf.c b/stand/libsa/printf.c
index 1602a2dc519d..4de547b644dd 100644
--- a/stand/libsa/printf.c
+++ b/stand/libsa/printf.c
@@ -271,6 +271,7 @@ kvprintf(char const *fmt, kvprintf_fn_t *func, void *arg, int radix, va_list ap)
 	char padc;
 	int stop = 0, retval = 0;
 
+	TSENTER();
 	num = 0;
 	if (!func)
 		d = (char *) arg;
@@ -287,8 +288,10 @@ kvprintf(char const *fmt, kvprintf_fn_t *func, void *arg, int radix, va_list ap)
 		padc = ' ';
 		width = 0;
 		while ((ch = (u_char)*fmt++) != '%' || stop) {
-			if (ch == '\0')
+			if (ch == '\0') {
+				TSEXIT();
 				return (retval);
+			}
 			PCHAR(ch);
 		}
 		percent = fmt - 1;
diff --git a/stand/libsa/tslog.c b/stand/libsa/tslog.c
index c6164aab02a9..a2791f9dc9c4 100644
--- a/stand/libsa/tslog.c
+++ b/stand/libsa/tslog.c
@@ -42,6 +42,24 @@ static char * tslog_buf = NULL;
 static size_t tslog_buflen = 0;
 static size_t tslog_bufpos = 0;
 
+static size_t
+tsccat(char * buf, uint64_t tsc)
+{
+	size_t len;
+
+	/* Handle upper digits. */
+	if (tsc >= 10)
+		len = tsccat(buf, tsc / 10);
+	else
+		len = 0;
+
+	/* Write the last digit. */
+	buf[len] = "0123456789"[tsc % 10];
+
+	/* Return the length written. */
+	return (len + 1);
+}
+
 void
 tslog_setbuf(void * buf, size_t len)
 {
@@ -69,16 +87,34 @@ tslog(const char * type, const char * f, const char * s)
 #else
 	uint64_t tsc = 0;
 #endif
-	int len;
 
 	/* If we have no buffer, do nothing. */
 	if (tslog_buf == NULL)
 		return;
 
-	/* Append to existing buffer, if we have enough space. */
-	len = snprintf(&tslog_buf[tslog_bufpos],
-	    tslog_buflen - tslog_bufpos, "0x0 %llu %s %s%s%s\n",
-	    (unsigned long long)tsc, type, f, s ? " " : "", s ? s : "");
-	if ((len > 0) && (tslog_bufpos + len <= tslog_buflen))
-		tslog_bufpos += len;
+	/* Check that we have enough space. */
+	if (tslog_buflen - tslog_bufpos < 32 + strlen(type) + strlen(f) +
+	    (s ? strlen(s) : 0))
+		return;
+
+	/* Append to existing buffer. */
+	strcpy(&tslog_buf[tslog_bufpos], "0x0 ");
+	tslog_bufpos += 4;
+	tslog_bufpos += tsccat(&tslog_buf[tslog_bufpos], tsc);
+	strcpy(&tslog_buf[tslog_bufpos], " ");
+	tslog_bufpos += 1;
+	strcpy(&tslog_buf[tslog_bufpos], type);
+	tslog_bufpos += strlen(type);
+	strcpy(&tslog_buf[tslog_bufpos], " ");
+	tslog_bufpos += 1;
+	strcpy(&tslog_buf[tslog_bufpos], f);
+	tslog_bufpos += strlen(f);
+	if (s != NULL) {
+		strcpy(&tslog_buf[tslog_bufpos], " ");
+		tslog_bufpos += 1;
+		strcpy(&tslog_buf[tslog_bufpos], s);
+		tslog_bufpos += strlen(s);
+	}
+	strcpy(&tslog_buf[tslog_bufpos], "\n");
+	tslog_bufpos += 1;
 }