forked from Minki/linux
perf tools: Support MIPS unwinding and dwarf-regs
Map perf APIs (perf_reg_name/get_arch_regstr/unwind__arch_reg_id) with
MIPS specific registers.
[ayan@wavecomp.com: repick this patch for unwinding userstack backtrace
by perf and libunwind on MIPS based CPU.]
[yangtiezhu@loongson.cn: Add sample_reg_masks[] to fix build error,
silence some checkpatch errors and warnings, and also separate the
original patches into two parts (MIPS kernel and perf tools) to merge
easily.]
The original patches:
https://lore.kernel.org/patchwork/patch/1126521/
https://lore.kernel.org/patchwork/patch/1126520/
Committer notes:
Do it as __perf_reg_name() to cope with:
067012974c
("perf tools: Fix arm64 build error with gcc-11")
Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Archer Yan <ayan@wavecomp.com>
Cc: David Daney <david.daney@cavium.com>
Cc: Jianlin Lv <Jianlin.Lv@arm.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Juxin Gao <gaojuxin@loongson.cn>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ralf Baechle <ralf@linux-mips.org>
Cc: Xuefeng Li <lixuefeng@loongson.cn>
Cc: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Cc: linux-mips@vger.kernel.org
Link: http://lore.kernel.org/lkml/1612409724-3516-3-git-send-email-yangtiezhu@loongson.cn
Signed-off-by: Archer Yan <ayan@wavecomp.com>
Signed-off-by: David Daney <david.daney@cavium.com>
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
84b7725536
commit
b5f184fbdb
@ -87,6 +87,12 @@ ifeq ($(ARCH),s390)
|
||||
CFLAGS += -fPIC -I$(OUTPUT)arch/s390/include/generated
|
||||
endif
|
||||
|
||||
ifeq ($(ARCH),mips)
|
||||
NO_PERF_REGS := 0
|
||||
CFLAGS += -I../../arch/mips/include/uapi -I../../arch/mips/include/generated/uapi
|
||||
LIBUNWIND_LIBS = -lunwind -lunwind-mips
|
||||
endif
|
||||
|
||||
ifeq ($(NO_PERF_REGS),0)
|
||||
$(call detected,CONFIG_PERF_REGS)
|
||||
endif
|
||||
|
4
tools/perf/arch/mips/Makefile
Normal file
4
tools/perf/arch/mips/Makefile
Normal file
@ -0,0 +1,4 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
ifndef NO_DWARF
|
||||
PERF_HAVE_DWARF_REGS := 1
|
||||
endif
|
31
tools/perf/arch/mips/include/dwarf-regs-table.h
Normal file
31
tools/perf/arch/mips/include/dwarf-regs-table.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* dwarf-regs-table.h : Mapping of DWARF debug register numbers into
|
||||
* register names.
|
||||
*
|
||||
* Copyright (C) 2013 Cavium, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef DEFINE_DWARF_REGSTR_TABLE
|
||||
#undef REG_DWARFNUM_NAME
|
||||
#define REG_DWARFNUM_NAME(reg, idx) [idx] = "$" #reg
|
||||
static const char * const mips_regstr_tbl[] = {
|
||||
"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
|
||||
"$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19",
|
||||
"$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "%29",
|
||||
"$30", "$31",
|
||||
REG_DWARFNUM_NAME(hi, 64),
|
||||
REG_DWARFNUM_NAME(lo, 65),
|
||||
};
|
||||
#endif
|
84
tools/perf/arch/mips/include/perf_regs.h
Normal file
84
tools/perf/arch/mips/include/perf_regs.h
Normal file
@ -0,0 +1,84 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef ARCH_PERF_REGS_H
|
||||
#define ARCH_PERF_REGS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/perf_regs.h>
|
||||
|
||||
#define PERF_REGS_MAX PERF_REG_MIPS_MAX
|
||||
#define PERF_REG_IP PERF_REG_MIPS_PC
|
||||
#define PERF_REG_SP PERF_REG_MIPS_R29
|
||||
|
||||
#define PERF_REGS_MASK ((1ULL << PERF_REG_MIPS_MAX) - 1)
|
||||
|
||||
static inline const char *__perf_reg_name(int id)
|
||||
{
|
||||
switch (id) {
|
||||
case PERF_REG_MIPS_PC:
|
||||
return "PC";
|
||||
case PERF_REG_MIPS_R1:
|
||||
return "$1";
|
||||
case PERF_REG_MIPS_R2:
|
||||
return "$2";
|
||||
case PERF_REG_MIPS_R3:
|
||||
return "$3";
|
||||
case PERF_REG_MIPS_R4:
|
||||
return "$4";
|
||||
case PERF_REG_MIPS_R5:
|
||||
return "$5";
|
||||
case PERF_REG_MIPS_R6:
|
||||
return "$6";
|
||||
case PERF_REG_MIPS_R7:
|
||||
return "$7";
|
||||
case PERF_REG_MIPS_R8:
|
||||
return "$8";
|
||||
case PERF_REG_MIPS_R9:
|
||||
return "$9";
|
||||
case PERF_REG_MIPS_R10:
|
||||
return "$10";
|
||||
case PERF_REG_MIPS_R11:
|
||||
return "$11";
|
||||
case PERF_REG_MIPS_R12:
|
||||
return "$12";
|
||||
case PERF_REG_MIPS_R13:
|
||||
return "$13";
|
||||
case PERF_REG_MIPS_R14:
|
||||
return "$14";
|
||||
case PERF_REG_MIPS_R15:
|
||||
return "$15";
|
||||
case PERF_REG_MIPS_R16:
|
||||
return "$16";
|
||||
case PERF_REG_MIPS_R17:
|
||||
return "$17";
|
||||
case PERF_REG_MIPS_R18:
|
||||
return "$18";
|
||||
case PERF_REG_MIPS_R19:
|
||||
return "$19";
|
||||
case PERF_REG_MIPS_R20:
|
||||
return "$20";
|
||||
case PERF_REG_MIPS_R21:
|
||||
return "$21";
|
||||
case PERF_REG_MIPS_R22:
|
||||
return "$22";
|
||||
case PERF_REG_MIPS_R23:
|
||||
return "$23";
|
||||
case PERF_REG_MIPS_R24:
|
||||
return "$24";
|
||||
case PERF_REG_MIPS_R25:
|
||||
return "$25";
|
||||
case PERF_REG_MIPS_R28:
|
||||
return "$28";
|
||||
case PERF_REG_MIPS_R29:
|
||||
return "$29";
|
||||
case PERF_REG_MIPS_R30:
|
||||
return "$30";
|
||||
case PERF_REG_MIPS_R31:
|
||||
return "$31";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* ARCH_PERF_REGS_H */
|
3
tools/perf/arch/mips/util/Build
Normal file
3
tools/perf/arch/mips/util/Build
Normal file
@ -0,0 +1,3 @@
|
||||
perf-y += perf_regs.o
|
||||
perf-$(CONFIG_DWARF) += dwarf-regs.o
|
||||
perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
|
38
tools/perf/arch/mips/util/dwarf-regs.c
Normal file
38
tools/perf/arch/mips/util/dwarf-regs.c
Normal file
@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
|
||||
*
|
||||
* Copyright (C) 2013 Cavium, Inc.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dwarf-regs.h>
|
||||
|
||||
static const char *mips_gpr_names[32] = {
|
||||
"$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
|
||||
"$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19",
|
||||
"$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29",
|
||||
"$30", "$31"
|
||||
};
|
||||
|
||||
const char *get_arch_regstr(unsigned int n)
|
||||
{
|
||||
if (n < 32)
|
||||
return mips_gpr_names[n];
|
||||
if (n == 64)
|
||||
return "hi";
|
||||
if (n == 65)
|
||||
return "lo";
|
||||
return NULL;
|
||||
}
|
6
tools/perf/arch/mips/util/perf_regs.c
Normal file
6
tools/perf/arch/mips/util/perf_regs.c
Normal file
@ -0,0 +1,6 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "../../util/perf_regs.h"
|
||||
|
||||
const struct sample_reg sample_reg_masks[] = {
|
||||
SMPL_REG_END
|
||||
};
|
22
tools/perf/arch/mips/util/unwind-libunwind.c
Normal file
22
tools/perf/arch/mips/util/unwind-libunwind.c
Normal file
@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
#include <errno.h>
|
||||
#include <libunwind.h>
|
||||
#include "perf_regs.h"
|
||||
#include "../../util/unwind.h"
|
||||
#include "util/debug.h"
|
||||
|
||||
int libunwind__arch_reg_id(int regnum)
|
||||
{
|
||||
switch (regnum) {
|
||||
case UNW_MIPS_R1 ... UNW_MIPS_R25:
|
||||
return regnum - UNW_MIPS_R1 + PERF_REG_MIPS_R1;
|
||||
case UNW_MIPS_R28 ... UNW_MIPS_R31:
|
||||
return regnum - UNW_MIPS_R28 + PERF_REG_MIPS_R28;
|
||||
case UNW_MIPS_PC:
|
||||
return PERF_REG_MIPS_PC;
|
||||
default:
|
||||
pr_err("unwind: invalid reg id %d\n", regnum);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@
|
||||
#include "../arch/s390/include/dwarf-regs-table.h"
|
||||
#include "../arch/sparc/include/dwarf-regs-table.h"
|
||||
#include "../arch/xtensa/include/dwarf-regs-table.h"
|
||||
#include "../arch/mips/include/dwarf-regs-table.h"
|
||||
|
||||
#define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
|
||||
|
||||
@ -53,6 +54,8 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine)
|
||||
return __get_dwarf_regstr(sparc_regstr_tbl, n);
|
||||
case EM_XTENSA:
|
||||
return __get_dwarf_regstr(xtensa_regstr_tbl, n);
|
||||
case EM_MIPS:
|
||||
return __get_dwarf_regstr(mips_regstr_tbl, n);
|
||||
default:
|
||||
pr_err("ELF MACHINE %x is not supported.\n", machine);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user