@@ -42,7 +42,7 @@ cc-option = $(shell if $(CC) $(1) -S -o /dev/null -xc /dev/null \
CFLAGS += -g
CFLAGS += $(autodepend-flags) -Wall
-CFLAGS += $(call cc-option, -fomit-frame-pointer, "")
+CFLAGS += $(call cc-option, -fno-omit-frame-pointer, "")
CFLAGS += $(call cc-option, -fno-stack-protector, "")
CFLAGS += $(call cc-option, -fno-stack-protector-all, "")
@@ -39,6 +39,7 @@ cflatobjs += lib/arm/mmu.o
cflatobjs += lib/arm/bitops.o
cflatobjs += lib/arm/psci.o
cflatobjs += lib/arm/smp.o
+cflatobjs += lib/arm/dump_stack.o
libeabi = lib/arm/libeabi.a
eabiobjs = lib/arm/eabi_compat.o
new file mode 100644
@@ -0,0 +1,6 @@
+#include "libcflat.h"
+
+int walk_stack(unsigned long bp, unsigned long *stack, int max_depth)
+{
+ return 0;
+}
@@ -65,6 +65,10 @@ extern void report_xfail(const char *msg_fmt, bool xfail, bool pass, ...);
extern void report_abort(const char *msg_fmt, ...);
extern int report_summary(void);
+int walk_stack(unsigned long bp, unsigned long *stack, int max_depth);
+void dump_stack(unsigned long ip, unsigned long bp);
+void dump_current_stack(void);
+
#define ARRAY_SIZE(_a) (sizeof(_a)/sizeof((_a)[0]))
#define container_of(ptr, type, member) ({ \
new file mode 100644
@@ -0,0 +1,6 @@
+#include "libcflat.h"
+
+int walk_stack(unsigned long bp, unsigned long *stack, int max_depth)
+{
+ return 0;
+}
@@ -259,3 +259,40 @@ int printf(const char *fmt, ...)
puts(buf);
return r;
}
+
+static void print_stack(unsigned long *stack, int depth,
+ bool top_is_return_address)
+{
+ int i;
+
+ printf("\tSTACK: " );
+ for (i = 0; i < depth; i++) {
+ int offset = -1;
+ if (i == 0 && !top_is_return_address)
+ offset = 0;
+ printf(" %lx", stack[i] + offset);
+ }
+ printf("\n");
+}
+
+#define MAX_DEPTH 10
+
+void dump_stack(unsigned long ip, unsigned long bp)
+{
+ unsigned long stack[MAX_DEPTH];
+ int depth;
+
+ stack[0] = ip;
+ depth = walk_stack(bp, &stack[1], MAX_DEPTH - 1);
+ print_stack(stack, depth + 1, false);
+}
+
+void dump_current_stack(void)
+{
+ unsigned long stack[MAX_DEPTH];
+ int depth;
+
+ depth = walk_stack((unsigned long)__builtin_frame_address(1), stack,
+ MAX_DEPTH);
+ print_stack(stack, depth, true);
+}
new file mode 100644
@@ -0,0 +1,24 @@
+#include "libcflat.h"
+
+int walk_stack(unsigned long bp, unsigned long *stack, int max_depth)
+{
+ static int walking;
+ int depth = 0;
+ unsigned long *frame = (unsigned long *) bp;
+
+ if (walking) {
+ printf("RECURSIVE STACK WALK!!!\n");
+ return 0;
+ }
+ walking = 1;
+
+ for (depth = 0; depth < max_depth; depth++) {
+ stack[depth] = frame[1];
+ if (stack[depth] == 0)
+ break;
+ frame = (unsigned long *) frame[0];
+ }
+
+ walking = 0;
+ return depth;
+}
@@ -30,6 +30,7 @@ cflatobjs += lib/powerpc/io.o
cflatobjs += lib/powerpc/hcall.o
cflatobjs += lib/powerpc/setup.o
cflatobjs += lib/powerpc/rtas.o
+cflatobjs += lib/powerpc/dump_stack.o
FLATLIBS = $(libcflat) $(LIBFDT_archive)
%.elf: LDFLAGS = $(arch_LDFLAGS) -nostdlib -pie
@@ -12,6 +12,7 @@ cflatobjs += lib/x86/atomic.o
cflatobjs += lib/x86/desc.o
cflatobjs += lib/x86/isr.o
cflatobjs += lib/x86/acpi.o
+cflatobjs += lib/x86/dump_stack.o
$(libcflat): LDFLAGS += -nostdlib
$(libcflat): CFLAGS += -ffreestanding -I lib
Functions to walk stack and print backtrace. The stack's unadorned as STACK: addr addr addr ... A follow-up patch post-processes the output to pretty-print the stack. Stack walker is just a stub on arm and ppc. Signed-off-by: Peter Feiner <pfeiner@google.com> --- Makefile | 2 +- arm/Makefile.common | 1 + lib/arm/dump_stack.c | 6 ++++++ lib/libcflat.h | 4 ++++ lib/powerpc/dump_stack.c | 6 ++++++ lib/printf.c | 37 +++++++++++++++++++++++++++++++++++++ lib/x86/dump_stack.c | 24 ++++++++++++++++++++++++ powerpc/Makefile.common | 1 + x86/Makefile.common | 1 + 9 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 lib/arm/dump_stack.c create mode 100644 lib/powerpc/dump_stack.c create mode 100644 lib/x86/dump_stack.c