diff mbox series

[1/3] core/utils: add snprintf_symbol

Message ID 20180202053410.16830-2-npiggin@gmail.com
State Accepted
Headers show
Series Improve exception handling | expand

Commit Message

Nicholas Piggin Feb. 2, 2018, 5:34 a.m. UTC
get_symbol is difficult to use. Add snprintf_symbol helper which
prints a symbol into a buffer with length, and returns the number
of bytes used, similarly to snprintf. Use this in the stack dumping
code rather than open-coding it.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 core/stack.c      | 17 ++++-------------
 core/utils.c      | 26 +++++++++++++++++++++++++-
 include/skiboot.h |  3 +--
 3 files changed, 30 insertions(+), 16 deletions(-)
diff mbox series

Patch

diff --git a/core/stack.c b/core/stack.c
index af4d37d01..e04a4ddb7 100644
--- a/core/stack.c
+++ b/core/stack.c
@@ -59,8 +59,7 @@  void __print_backtrace(unsigned int pir,
 	static char bt_text_buf[4096];
 	int i, l = 0, max;
 	char *buf = out_buf;
-	unsigned long bottom, top, tbot, ttop, saddr = 0;
-	char *sym = NULL, *sym_end = NULL;
+	unsigned long bottom, top, tbot, ttop;
 	char mark;
 
 	if (!out_buf) {
@@ -82,20 +81,12 @@  void __print_backtrace(unsigned int pir,
 			mark = '*';
 		else
 			mark = ' ';
-		if (symbols)
-			saddr = get_symbol(entries->pc, &sym, &sym_end);
-		else
-			saddr = 0;
 		l += snprintf(buf + l, max - l,
 			      " S: %016lx R: %016lx %c ",
 			      entries->sp, entries->pc, mark);
-		while(saddr && sym < sym_end && l < max)
-			buf[l++] = *(sym++);
-		if (sym && l < max)
-			l += snprintf(buf + l, max - l, "+0x%lx\n",
-				      entries->pc - saddr);
-		else
-			l += snprintf(buf + l, max - l, "\n");
+		if (symbols)
+			l += snprintf_symbol(buf + l, max - l, entries->pc);
+		l += snprintf(buf + l, max - l, "\n");
 		entries++;
 	}
 	if (!out_buf)
diff --git a/core/utils.c b/core/utils.c
index 9e2cb37c8..508bba912 100644
--- a/core/utils.c
+++ b/core/utils.c
@@ -61,7 +61,7 @@  char __attrconst tohex(uint8_t nibble)
 	return __tohex[nibble];
 }
 
-unsigned long get_symbol(unsigned long addr, char **sym, char **sym_end)
+static unsigned long get_symbol(unsigned long addr, char **sym, char **sym_end)
 {
 	unsigned long prev = 0, next;
 	char *psym = NULL, *p = __sym_map_start;
@@ -88,3 +88,27 @@  unsigned long get_symbol(unsigned long addr, char **sym, char **sym_end)
 	return 0;
 }
 
+size_t snprintf_symbol(char *buf, size_t len, uint64_t addr)
+{
+	unsigned long saddr;
+	char *sym, *sym_end;
+	size_t l;
+
+	saddr = get_symbol(addr, &sym, &sym_end);
+	if (!saddr)
+		return 0;
+
+	if (len > sym_end - sym)
+		l = sym_end - sym;
+	else
+		l = len - 1;
+	memcpy(buf, sym, l);
+
+	/*
+	 * This snprintf will insert the terminating NUL even if the
+	 * symbol has used up the entire buffer less 1.
+	 */
+	l += snprintf(buf + l, len - l, "+0x%llx", addr - saddr);
+
+	return l;
+}
diff --git a/include/skiboot.h b/include/skiboot.h
index e94f21212..fd751dced 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -204,8 +204,7 @@  extern const char version[];
 /* Debug support */
 extern char __sym_map_start[];
 extern char __sym_map_end[];
-extern unsigned long get_symbol(unsigned long addr,
-				char **sym, char **sym_end);
+extern size_t snprintf_symbol(char *buf, size_t len, uint64_t addr);
 
 /* Direct controls */
 extern void direct_controls_init(void);