Add support for Linux-like kallsysms

The kernel stores address<->symbol names in it so things can be decoded at
runtime.  Do it in U-Boot, and we get nice symbol decoding when crashing.

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
diff --git a/common/kallsyms.c b/common/kallsyms.c
new file mode 100644
index 0000000..ce42a93
--- /dev/null
+++ b/common/kallsyms.c
@@ -0,0 +1,44 @@
+/*
+ * Helper functions for working with the builtin symbol table
+ *
+ * Copyright (c) 2008-2009 Analog Devices Inc.
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+
+/* We need the weak marking as this symbol is provided specially */
+extern const char system_map[] __attribute__((weak));
+
+/* Given an address, return a pointer to the symbol name and store
+ * the base address in caddr.  So if the symbol map had an entry:
+ *		03fb9b7c_spi_cs_deactivate
+ * Then the following call:
+ *		unsigned long base;
+ *		const char *sym = symbol_lookup(0x03fb9b80, &base);
+ * Would end up setting the variables like so:
+ *		base = 0x03fb9b7c;
+ *		sym = "_spi_cs_deactivate";
+ */
+const char *symbol_lookup(unsigned long addr, unsigned long *caddr)
+{
+	const char *sym, *csym;
+	char *esym;
+	unsigned long sym_addr;
+
+	sym = system_map;
+	csym = NULL;
+	*caddr = 0;
+
+	while (*sym) {
+		sym_addr = simple_strtoul(sym, &esym, 16);
+		sym = esym;
+		if (sym_addr > addr)
+			break;
+		*caddr = sym_addr;
+		csym = sym;
+		sym += strlen(sym) + 1;
+	}
+
+	return csym;
+}