^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #ifndef _ASM_S390_STACKTRACE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #define _ASM_S390_STACKTRACE_H
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <asm/switch_to.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) enum stack_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) STACK_TYPE_UNKNOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) STACK_TYPE_TASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) STACK_TYPE_IRQ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) STACK_TYPE_NODAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) STACK_TYPE_RESTART,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) struct stack_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) enum stack_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) unsigned long begin, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) const char *stack_type_name(enum stack_type type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) int get_stack_info(unsigned long sp, struct task_struct *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct stack_info *info, unsigned long *visit_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) static inline bool on_stack(struct stack_info *info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) unsigned long addr, size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) if (info->type == STACK_TYPE_UNKNOWN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) if (addr + len < addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) return addr >= info->begin && addr + len <= info->end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static __always_inline unsigned long get_stack_pointer(struct task_struct *task,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return (unsigned long) kernel_stack_pointer(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (task == current)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) return current_stack_pointer();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) return (unsigned long) task->thread.ksp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * Stack layout of a C stack frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #ifndef __PACK_STACK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct stack_frame {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) unsigned long back_chain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) unsigned long empty1[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) unsigned long gprs[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) unsigned int empty2[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) struct stack_frame {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) unsigned long empty1[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) unsigned int empty2[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) unsigned long gprs[10];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) unsigned long back_chain;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * Unlike current_stack_pointer() which simply returns current value of %r15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * current_frame_address() returns function stack frame address, which matches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * %r15 upon function invocation. It may differ from %r15 later if function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * allocates stack for local variables or new stack frame to call other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define current_frame_address() \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) ((unsigned long)__builtin_frame_address(0) - \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) offsetof(struct stack_frame, back_chain))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define CALL_ARGS_0() \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) register unsigned long r2 asm("2")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define CALL_ARGS_1(arg1) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) register unsigned long r2 asm("2") = (unsigned long)(arg1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define CALL_ARGS_2(arg1, arg2) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) CALL_ARGS_1(arg1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) register unsigned long r3 asm("3") = (unsigned long)(arg2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define CALL_ARGS_3(arg1, arg2, arg3) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) CALL_ARGS_2(arg1, arg2); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) register unsigned long r4 asm("4") = (unsigned long)(arg3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define CALL_ARGS_4(arg1, arg2, arg3, arg4) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) CALL_ARGS_3(arg1, arg2, arg3); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) register unsigned long r4 asm("5") = (unsigned long)(arg4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define CALL_ARGS_5(arg1, arg2, arg3, arg4, arg5) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) CALL_ARGS_4(arg1, arg2, arg3, arg4); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) register unsigned long r4 asm("6") = (unsigned long)(arg5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * To keep this simple mark register 2-6 as being changed (volatile)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * by the called function, even though register 6 is saved/nonvolatile.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define CALL_FMT_0 "=&d" (r2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define CALL_FMT_1 "+&d" (r2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define CALL_FMT_2 CALL_FMT_1, "+&d" (r3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define CALL_FMT_3 CALL_FMT_2, "+&d" (r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define CALL_FMT_4 CALL_FMT_3, "+&d" (r5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define CALL_FMT_5 CALL_FMT_4, "+&d" (r6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define CALL_CLOBBER_5 "0", "1", "14", "cc", "memory"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) #define CALL_CLOBBER_4 CALL_CLOBBER_5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define CALL_CLOBBER_3 CALL_CLOBBER_4, "5"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) #define CALL_CLOBBER_2 CALL_CLOBBER_3, "4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) #define CALL_CLOBBER_1 CALL_CLOBBER_2, "3"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) #define CALL_CLOBBER_0 CALL_CLOBBER_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define CALL_ON_STACK(fn, stack, nr, args...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) unsigned long frame = current_frame_address(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) CALL_ARGS_##nr(args); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) unsigned long prev; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) asm volatile( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) " la %[_prev],0(15)\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) " lg 15,%[_stack]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) " stg %[_frame],%[_bc](15)\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) " brasl 14,%[_fn]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) " la 15,0(%[_prev])\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) : [_prev] "=&a" (prev), CALL_FMT_##nr \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) : [_stack] "R" (stack), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) [_bc] "i" (offsetof(struct stack_frame, back_chain)), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) [_frame] "d" (frame), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) [_fn] "X" (fn) : CALL_CLOBBER_##nr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) r2; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) #define CALL_LARGS_0(...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) long dummy = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #define CALL_LARGS_1(t1, a1) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) long arg1 = (long)(t1)(a1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) #define CALL_LARGS_2(t1, a1, t2, a2) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) CALL_LARGS_1(t1, a1); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) long arg2 = (long)(t2)(a2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define CALL_LARGS_3(t1, a1, t2, a2, t3, a3) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) CALL_LARGS_2(t1, a1, t2, a2); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) long arg3 = (long)(t3)(a3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) #define CALL_LARGS_4(t1, a1, t2, a2, t3, a3, t4, a4) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) CALL_LARGS_3(t1, a1, t2, a2, t3, a3); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) long arg4 = (long)(t4)(a4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) #define CALL_LARGS_5(t1, a1, t2, a2, t3, a3, t4, a4, t5, a5) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) CALL_LARGS_4(t1, a1, t2, a2, t3, a3, t4, a4); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) long arg5 = (long)(t5)(a5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define CALL_REGS_0 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) register long r2 asm("2") = dummy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #define CALL_REGS_1 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) register long r2 asm("2") = arg1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) #define CALL_REGS_2 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) CALL_REGS_1; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) register long r3 asm("3") = arg2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define CALL_REGS_3 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) CALL_REGS_2; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) register long r4 asm("4") = arg3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) #define CALL_REGS_4 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) CALL_REGS_3; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) register long r5 asm("5") = arg4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) #define CALL_REGS_5 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) CALL_REGS_4; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) register long r6 asm("6") = arg5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define CALL_TYPECHECK_0(...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define CALL_TYPECHECK_1(t, a, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) typecheck(t, a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) #define CALL_TYPECHECK_2(t, a, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) CALL_TYPECHECK_1(__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) typecheck(t, a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define CALL_TYPECHECK_3(t, a, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) CALL_TYPECHECK_2(__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) typecheck(t, a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define CALL_TYPECHECK_4(t, a, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) CALL_TYPECHECK_3(__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) typecheck(t, a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define CALL_TYPECHECK_5(t, a, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) CALL_TYPECHECK_4(__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) typecheck(t, a)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define CALL_PARM_0(...) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define CALL_PARM_1(t, a, ...) t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define CALL_PARM_2(t, a, ...) t, CALL_PARM_1(__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define CALL_PARM_3(t, a, ...) t, CALL_PARM_2(__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define CALL_PARM_4(t, a, ...) t, CALL_PARM_3(__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define CALL_PARM_5(t, a, ...) t, CALL_PARM_4(__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define CALL_PARM_6(t, a, ...) t, CALL_PARM_5(__VA_ARGS__)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Use call_on_stack() to call a function switching to a specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * stack. Proper sign and zero extension of function arguments is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * done. Usage:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * rc = call_on_stack(nr, stack, rettype, fn, t1, a1, t2, a2, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * - nr specifies the number of function arguments of fn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) * - stack specifies the stack to be used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * - fn is the function to be called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) * - rettype is the return type of fn.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * - t1, a1, ... are pairs, where t1 must match the type of the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * argument of fn, t2 the second, etc. a1 is the corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * first function argument (not name), etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define call_on_stack(nr, stack, rettype, fn, ...) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) rettype (*__fn)(CALL_PARM_##nr(__VA_ARGS__)) = fn; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) unsigned long frame = current_frame_address(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) unsigned long __stack = stack; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) unsigned long prev; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) CALL_LARGS_##nr(__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) CALL_REGS_##nr; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) CALL_TYPECHECK_##nr(__VA_ARGS__); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) asm volatile( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) " lgr %[_prev],15\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) " lg 15,%[_stack]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) " stg %[_frame],%[_bc](15)\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) " brasl 14,%[_fn]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) " lgr 15,%[_prev]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) : [_prev] "=&d" (prev), CALL_FMT_##nr \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) : [_stack] "R" (__stack), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) [_bc] "i" (offsetof(struct stack_frame, back_chain)), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) [_frame] "d" (frame), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) [_fn] "X" (__fn) : CALL_CLOBBER_##nr); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) (rettype)r2; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #define CALL_ON_STACK_NORETURN(fn, stack) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ({ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) asm volatile( \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) " la 15,0(%[_stack])\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) " xc %[_bc](8,15),%[_bc](15)\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) " brasl 14,%[_fn]\n" \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) ::[_bc] "i" (offsetof(struct stack_frame, back_chain)), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) [_stack] "a" (stack), [_fn] "X" (fn)); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) BUG(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) })
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) #endif /* _ASM_S390_STACKTRACE_H */