aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/stack.c17
-rw-r--r--core/utils.c26
-rw-r--r--include/skiboot.h3
3 files changed, 30 insertions, 16 deletions
diff --git a/core/stack.c b/core/stack.c
index af4d37d..e04a4dd 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 9e2cb37..508bba9 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 e94f212..fd751dc 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);