@@ -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)
@@ -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;
+}
@@ -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);
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(-)