Skip to content
Snippets Groups Projects
Select Git revision
  • c280f7736ab26a601932b1ce017a3840dbedcfdc
  • openEuler-1.0-LTS default protected
  • OLK-5.10
  • openEuler-22.09
  • openEuler-22.03-LTS
  • openEuler-22.03-LTS-Ascend
  • master
  • openEuler-22.03-LTS-LoongArch-NW
  • openEuler-22.09-HCK
  • openEuler-20.03-LTS-SP3
  • openEuler-21.09
  • openEuler-21.03
  • openEuler-20.09
  • 4.19.90-2210.5.0
  • 5.10.0-123.0.0
  • 5.10.0-60.63.0
  • 5.10.0-60.62.0
  • 4.19.90-2210.4.0
  • 5.10.0-121.0.0
  • 5.10.0-60.61.0
  • 4.19.90-2210.3.0
  • 5.10.0-60.60.0
  • 5.10.0-120.0.0
  • 5.10.0-60.59.0
  • 5.10.0-119.0.0
  • 4.19.90-2210.2.0
  • 4.19.90-2210.1.0
  • 5.10.0-118.0.0
  • 5.10.0-106.19.0
  • 5.10.0-60.58.0
  • 4.19.90-2209.6.0
  • 5.10.0-106.18.0
  • 5.10.0-106.17.0
33 results

unwind_frame.c

Blame
  • unwind_frame.c 7.10 KiB
    #include <linux/sched.h>
    #include <asm/ptrace.h>
    #include <asm/bitops.h>
    #include <asm/stacktrace.h>
    #include <asm/unwind.h>
    
    #define FRAME_HEADER_SIZE (sizeof(long) * 2)
    
    static void unwind_dump(struct unwind_state *state, unsigned long *sp)
    {
    	static bool dumped_before = false;
    	bool prev_zero, zero = false;
    	unsigned long word;
    
    	if (dumped_before)
    		return;
    
    	dumped_before = true;
    
    	printk_deferred("unwind stack type:%d next_sp:%p mask:%lx graph_idx:%d\n",
    			state->stack_info.type, state->stack_info.next_sp,
    			state->stack_mask, state->graph_idx);
    
    	for (sp = state->orig_sp; sp < state->stack_info.end; sp++) {
    		word = READ_ONCE_NOCHECK(*sp);
    
    		prev_zero = zero;
    		zero = word == 0;
    
    		if (zero) {
    			if (!prev_zero)
    				printk_deferred("%p: %016x ...\n", sp, 0);
    			continue;
    		}
    
    		printk_deferred("%p: %016lx (%pB)\n", sp, word, (void *)word);
    	}
    }
    
    unsigned long unwind_get_return_address(struct unwind_state *state)
    {
    	unsigned long addr;
    	unsigned long *addr_p = unwind_get_return_address_ptr(state);
    
    	if (unwind_done(state))
    		return 0;
    
    	if (state->regs && user_mode(state->regs))
    		return 0;
    
    	addr = ftrace_graph_ret_addr(state->task, &state->graph_idx, *addr_p,
    				     addr_p);
    
    	return __kernel_text_address(addr) ? addr : 0;
    }
    EXPORT_SYMBOL_GPL(unwind_get_return_address);
    
    static size_t regs_size(struct pt_regs *regs)
    {
    	/* x86_32 regs from kernel mode are two words shorter: */
    	if (IS_ENABLED(CONFIG_X86_32) && !user_mode(regs))
    		return sizeof(*regs) - 2*sizeof(long);
    
    	return sizeof(*regs);
    }
    
    static bool is_last_task_frame(struct unwind_state *state)
    {
    	unsigned long bp = (unsigned long)state->bp;
    	unsigned long regs = (unsigned long)task_pt_regs(state->task);