After the stack changes we can finally use -mbackchain and have a working backtrace. Signed-off-by: Janosch Frank <frankja@xxxxxxxxxxxxx> --- lib/s390x/stack.c | 20 ++++++++++++++------ s390x/Makefile | 1 + s390x/macros.S | 5 +++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/s390x/stack.c b/lib/s390x/stack.c index 0fcd1afb..4cf80dae 100644 --- a/lib/s390x/stack.c +++ b/lib/s390x/stack.c @@ -3,24 +3,32 @@ * s390x stack implementation * * Copyright (c) 2017 Red Hat Inc + * Copyright 2021 IBM Corp * * Authors: * Thomas Huth <thuth@xxxxxxxxxx> * David Hildenbrand <david@xxxxxxxxxx> + * Janosch Frank <frankja@xxxxxxxxxx> */ #include <libcflat.h> #include <stack.h> +#include <asm/arch_def.h> int backtrace_frame(const void *frame, const void **return_addrs, int max_depth) { - printf("TODO: Implement backtrace_frame(%p, %p, %d) function!\n", - frame, return_addrs, max_depth); - return 0; + int depth = 0; + struct stack_frame *stack = (struct stack_frame *)frame; + + for (depth = 0; stack && depth < max_depth; depth++) { + return_addrs[depth] = (void *)stack->grs[8]; + stack = stack->back_chain; + } + + return depth; } int backtrace(const void **return_addrs, int max_depth) { - printf("TODO: Implement backtrace(%p, %d) function!\n", - return_addrs, max_depth); - return 0; + return backtrace_frame(__builtin_frame_address(0), + return_addrs, max_depth); } diff --git a/s390x/Makefile b/s390x/Makefile index f3b0fccf..20bb5683 100644 --- a/s390x/Makefile +++ b/s390x/Makefile @@ -39,6 +39,7 @@ CFLAGS += -ffreestanding CFLAGS += -I $(SRCDIR)/lib -I $(SRCDIR)/lib/s390x -I lib CFLAGS += -O2 CFLAGS += -march=zEC12 +CFLAGS += -mbackchain CFLAGS += -fno-delete-null-pointer-checks LDFLAGS += -nostdlib -Wl,--build-id=none diff --git a/s390x/macros.S b/s390x/macros.S index 11f4397a..d4f41ec4 100644 --- a/s390x/macros.S +++ b/s390x/macros.S @@ -22,6 +22,11 @@ lgr %r2, %r15 /* Allocate stack space for called C function, as specified in s390 ELF ABI */ slgfi %r15, 160 + /* + * Save the address of the interrupt stack into the back chain + * of the called function. + */ + stg %r2, STACK_FRAME_INT_BACKCHAIN(%r15) brasl %r14, \c_func algfi %r15, 160 RESTORE_REGS_STACK -- 2.25.1