linux/arch/arm64/kernel/return_address.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * arch/arm64/kernel/return_address.c
   4 *
   5 * Copyright (C) 2013 Linaro Limited
   6 * Author: AKASHI Takahiro <takahiro.akashi@linaro.org>
   7 */
   8
   9#include <linux/export.h>
  10#include <linux/ftrace.h>
  11#include <linux/kprobes.h>
  12
  13#include <asm/stack_pointer.h>
  14#include <asm/stacktrace.h>
  15
  16struct return_address_data {
  17        unsigned int level;
  18        void *addr;
  19};
  20
  21static bool save_return_addr(void *d, unsigned long pc)
  22{
  23        struct return_address_data *data = d;
  24
  25        if (!data->level) {
  26                data->addr = (void *)pc;
  27                return false;
  28        } else {
  29                --data->level;
  30                return true;
  31        }
  32}
  33NOKPROBE_SYMBOL(save_return_addr);
  34
  35void *return_address(unsigned int level)
  36{
  37        struct return_address_data data;
  38        struct stackframe frame;
  39
  40        data.level = level + 2;
  41        data.addr = NULL;
  42
  43        start_backtrace(&frame,
  44                        (unsigned long)__builtin_frame_address(0),
  45                        (unsigned long)return_address);
  46        walk_stackframe(current, &frame, save_return_addr, &data);
  47
  48        if (!data.level)
  49                return data.addr;
  50        else
  51                return NULL;
  52}
  53EXPORT_SYMBOL_GPL(return_address);
  54NOKPROBE_SYMBOL(return_address);
  55