aboutsummaryrefslogtreecommitdiffstats
path: root/roms/skiboot/core/utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/skiboot/core/utils.c')
-rw-r--r--roms/skiboot/core/utils.c101
1 files changed, 101 insertions, 0 deletions
diff --git a/roms/skiboot/core/utils.c b/roms/skiboot/core/utils.c
new file mode 100644
index 000000000..0d2f5e894
--- /dev/null
+++ b/roms/skiboot/core/utils.c
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+/*
+ * Misc utility functions
+ *
+ * Copyright 2013-2018 IBM Corp.
+ */
+
+#include <skiboot.h>
+#include <lock.h>
+#include <fsp.h>
+#include <platform.h>
+#include <processor.h>
+#include <cpu.h>
+#include <stack.h>
+
+void __noreturn assert_fail(const char *msg, const char *file,
+ unsigned int line, const char *function)
+{
+ static bool in_abort = false;
+
+ (void)function;
+ if (in_abort)
+ for (;;) ;
+ in_abort = true;
+
+ /**
+ * @fwts-label FailedAssert2
+ * @fwts-advice OPAL hit an assert(). During normal usage (even
+ * testing) we should never hit an assert. There are other code
+ * paths for controlled shutdown/panic in the event of catastrophic
+ * errors.
+ */
+ prlog(PR_EMERG, "assert failed at %s:%u: %s\n", file, line, msg);
+ backtrace();
+
+ if (platform.terminate)
+ platform.terminate(msg);
+
+ for (;;) ;
+}
+
+char __attrconst tohex(uint8_t nibble)
+{
+ static const char __tohex[] = {'0','1','2','3','4','5','6','7','8','9',
+ 'A','B','C','D','E','F'};
+ if (nibble > 0xf)
+ return '?';
+ return __tohex[nibble];
+}
+
+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;
+
+ *sym = *sym_end = NULL;
+ while(p < __sym_map_end) {
+ next = strtoul(p, &p, 16) | SKIBOOT_BASE;
+ if (next > addr && prev <= addr) {
+ p = psym + 3;;
+ if (p >= __sym_map_end)
+ return 0;
+ *sym = p;
+ while(p < __sym_map_end && *p != 10)
+ p++;
+ *sym_end = p;
+ return prev;
+ }
+ prev = next;
+ psym = p;
+ while(p < __sym_map_end && *p != 10)
+ p++;
+ p++;
+ }
+ 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;
+}