linux/arch/sh/kernel/return_address.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * arch/sh/kernel/return_address.c
   4 *
   5 * Copyright (C) 2009  Matt Fleming
   6 * Copyright (C) 2009  Paul Mundt
   7 */
   8#include <linux/kernel.h>
   9#include <linux/module.h>
  10#include <asm/dwarf.h>
  11
  12#ifdef CONFIG_DWARF_UNWINDER
  13
  14void *return_address(unsigned int depth)
  15{
  16        struct dwarf_frame *frame;
  17        unsigned long ra;
  18        int i;
  19
  20        for (i = 0, frame = NULL, ra = 0; i <= depth; i++) {
  21                struct dwarf_frame *tmp;
  22
  23                tmp = dwarf_unwind_stack(ra, frame);
  24                if (!tmp)
  25                        return NULL;
  26
  27                if (frame)
  28                        dwarf_free_frame(frame);
  29
  30                frame = tmp;
  31
  32                if (!frame || !frame->return_addr)
  33                        break;
  34
  35                ra = frame->return_addr;
  36        }
  37
  38        /* Failed to unwind the stack to the specified depth. */
  39        WARN_ON(i != depth + 1);
  40
  41        if (frame)
  42                dwarf_free_frame(frame);
  43
  44        return (void *)ra;
  45}
  46
  47#else
  48
  49void *return_address(unsigned int depth)
  50{
  51        return NULL;
  52}
  53
  54#endif
  55
  56EXPORT_SYMBOL_GPL(return_address);
  57