aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHendrik Brueckner <brueckner@linux.vnet.ibm.com>2017-11-08 03:01:12 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2017-11-16 09:06:13 -0500
commita9fc2db0a8abf51c81122799c5ae4808f2324b6d (patch)
tree7327258f0fa6a4e70d87d91c3d1db04faaabcdd6
parentf704ef44602fbf403e6722c7ed13f62d17e8cb20 (diff)
s390/perf: define common DWARF register string table
Instead of defining DWARF register to string table in dwarf-regs-table.h and dwarf-regs.c, use a common table in dwarf-regs-table.h. Ensure that the DWARF register table is up-to-date with http://refspecs.linuxfoundation.org/ELF/zSeries/lzsabi0_s390/x1542.html. For unwinding with libdw, also ensure to correctly setup the DWARF register frame according to the register mappings. Currently, libdw supports up to 32 registers only. Suggested-by: Thomas Richter <tmricht@linux.vnet.ibm.com> Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Reviewed-and-tested-by: Thomas Richter <tmricht@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--tools/perf/arch/s390/include/dwarf-regs-table.h71
-rw-r--r--tools/perf/arch/s390/util/dwarf-regs.c15
-rw-r--r--tools/perf/arch/s390/util/unwind-libdw.c15
3 files changed, 80 insertions, 21 deletions
diff --git a/tools/perf/arch/s390/include/dwarf-regs-table.h b/tools/perf/arch/s390/include/dwarf-regs-table.h
index 792d4c277225..671553525f41 100644
--- a/tools/perf/arch/s390/include/dwarf-regs-table.h
+++ b/tools/perf/arch/s390/include/dwarf-regs-table.h
@@ -1,9 +1,72 @@
1/* SPDX-License-Identifier: GPL-2.0 */ 1/* SPDX-License-Identifier: GPL-2.0 */
2#ifdef DEFINE_DWARF_REGSTR_TABLE 2#ifndef S390_DWARF_REGS_TABLE_H
3/* This is included in perf/util/dwarf-regs.c */ 3#define S390_DWARF_REGS_TABLE_H
4 4
5static const char * const s390_regstr_tbl[] = { 5#define REG_DWARFNUM_NAME(reg, idx) [idx] = "%" #reg
6
7/*
8 * For reference, see DWARF register mapping:
9 * http://refspecs.linuxfoundation.org/ELF/zSeries/lzsabi0_s390/x1542.html
10 */
11static const char * const s390_dwarf_regs[] = {
6 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", 12 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
7 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", 13 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
14 REG_DWARFNUM_NAME(f0, 16),
15 REG_DWARFNUM_NAME(f1, 20),
16 REG_DWARFNUM_NAME(f2, 17),
17 REG_DWARFNUM_NAME(f3, 21),
18 REG_DWARFNUM_NAME(f4, 18),
19 REG_DWARFNUM_NAME(f5, 22),
20 REG_DWARFNUM_NAME(f6, 19),
21 REG_DWARFNUM_NAME(f7, 23),
22 REG_DWARFNUM_NAME(f8, 24),
23 REG_DWARFNUM_NAME(f9, 28),
24 REG_DWARFNUM_NAME(f10, 25),
25 REG_DWARFNUM_NAME(f11, 29),
26 REG_DWARFNUM_NAME(f12, 26),
27 REG_DWARFNUM_NAME(f13, 30),
28 REG_DWARFNUM_NAME(f14, 27),
29 REG_DWARFNUM_NAME(f15, 31),
30 REG_DWARFNUM_NAME(c0, 32),
31 REG_DWARFNUM_NAME(c1, 33),
32 REG_DWARFNUM_NAME(c2, 34),
33 REG_DWARFNUM_NAME(c3, 35),
34 REG_DWARFNUM_NAME(c4, 36),
35 REG_DWARFNUM_NAME(c5, 37),
36 REG_DWARFNUM_NAME(c6, 38),
37 REG_DWARFNUM_NAME(c7, 39),
38 REG_DWARFNUM_NAME(c8, 40),
39 REG_DWARFNUM_NAME(c9, 41),
40 REG_DWARFNUM_NAME(c10, 42),
41 REG_DWARFNUM_NAME(c11, 43),
42 REG_DWARFNUM_NAME(c12, 44),
43 REG_DWARFNUM_NAME(c13, 45),
44 REG_DWARFNUM_NAME(c14, 46),
45 REG_DWARFNUM_NAME(c15, 47),
46 REG_DWARFNUM_NAME(a0, 48),
47 REG_DWARFNUM_NAME(a1, 49),
48 REG_DWARFNUM_NAME(a2, 50),
49 REG_DWARFNUM_NAME(a3, 51),
50 REG_DWARFNUM_NAME(a4, 52),
51 REG_DWARFNUM_NAME(a5, 53),
52 REG_DWARFNUM_NAME(a6, 54),
53 REG_DWARFNUM_NAME(a7, 55),
54 REG_DWARFNUM_NAME(a8, 56),
55 REG_DWARFNUM_NAME(a9, 57),
56 REG_DWARFNUM_NAME(a10, 58),
57 REG_DWARFNUM_NAME(a11, 59),
58 REG_DWARFNUM_NAME(a12, 60),
59 REG_DWARFNUM_NAME(a13, 61),
60 REG_DWARFNUM_NAME(a14, 62),
61 REG_DWARFNUM_NAME(a15, 63),
62 REG_DWARFNUM_NAME(pswm, 64),
63 REG_DWARFNUM_NAME(pswa, 65),
8}; 64};
9#endif 65
66#ifdef DEFINE_DWARF_REGSTR_TABLE
67/* This is included in perf/util/dwarf-regs.c */
68
69#define s390_regstr_tbl s390_dwarf_regs
70
71#endif /* DEFINE_DWARF_REGSTR_TABLE */
72#endif /* S390_DWARF_REGS_TABLE_H */
diff --git a/tools/perf/arch/s390/util/dwarf-regs.c b/tools/perf/arch/s390/util/dwarf-regs.c
index 0cd7cba5d6ee..f47576ce13ea 100644
--- a/tools/perf/arch/s390/util/dwarf-regs.c
+++ b/tools/perf/arch/s390/util/dwarf-regs.c
@@ -9,19 +9,10 @@
9 9
10#include <stddef.h> 10#include <stddef.h>
11#include <dwarf-regs.h> 11#include <dwarf-regs.h>
12 12#include <linux/kernel.h>
13#define NUM_GPRS 16 13#include "dwarf-regs-table.h"
14
15static const char *gpr_names[NUM_GPRS] = {
16 "%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7",
17 "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",
18};
19 14
20const char *get_arch_regstr(unsigned int n) 15const char *get_arch_regstr(unsigned int n)
21{ 16{
22 if (n == 64) 17 return (n >= ARRAY_SIZE(s390_dwarf_regs)) ? NULL : s390_dwarf_regs[n];
23 return "mask";
24 if (n == 65)
25 return "pc";
26 return (n >= NUM_GPRS) ? NULL : gpr_names[n];
27} 18}
diff --git a/tools/perf/arch/s390/util/unwind-libdw.c b/tools/perf/arch/s390/util/unwind-libdw.c
index 281bbb82402a..ba8d98b8b09e 100644
--- a/tools/perf/arch/s390/util/unwind-libdw.c
+++ b/tools/perf/arch/s390/util/unwind-libdw.c
@@ -1,21 +1,26 @@
1#include <linux/kernel.h>
1#include <elfutils/libdwfl.h> 2#include <elfutils/libdwfl.h>
2#include "../../util/unwind-libdw.h" 3#include "../../util/unwind-libdw.h"
3#include "../../util/perf_regs.h" 4#include "../../util/perf_regs.h"
4#include "../../util/event.h" 5#include "../../util/event.h"
6#include "dwarf-regs-table.h"
5 7
6 8
7bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) 9bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg)
8{ 10{
9 struct unwind_info *ui = arg; 11 struct unwind_info *ui = arg;
10 struct regs_dump *user_regs = &ui->sample->user_regs; 12 struct regs_dump *user_regs = &ui->sample->user_regs;
11 Dwarf_Word dwarf_regs[PERF_REG_S390_MAX]; 13 Dwarf_Word dwarf_regs[ARRAY_SIZE(s390_dwarf_regs)];
12 14
13#define REG(r) ({ \ 15#define REG(r) ({ \
14 Dwarf_Word val = 0; \ 16 Dwarf_Word val = 0; \
15 perf_reg_value(&val, user_regs, PERF_REG_S390_##r); \ 17 perf_reg_value(&val, user_regs, PERF_REG_S390_##r); \
16 val; \ 18 val; \
17}) 19})
18 20 /*
21 * For DWARF register mapping details,
22 * see also perf/arch/s390/include/dwarf-regs-table.h
23 */
19 dwarf_regs[0] = REG(R0); 24 dwarf_regs[0] = REG(R0);
20 dwarf_regs[1] = REG(R1); 25 dwarf_regs[1] = REG(R1);
21 dwarf_regs[2] = REG(R2); 26 dwarf_regs[2] = REG(R2);
@@ -32,9 +37,9 @@ bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg)
32 dwarf_regs[13] = REG(R13); 37 dwarf_regs[13] = REG(R13);
33 dwarf_regs[14] = REG(R14); 38 dwarf_regs[14] = REG(R14);
34 dwarf_regs[15] = REG(R15); 39 dwarf_regs[15] = REG(R15);
35 dwarf_regs[16] = REG(MASK); 40 dwarf_regs[64] = REG(MASK);
36 dwarf_regs[17] = REG(PC); 41 dwarf_regs[65] = REG(PC);
37 42
38 dwfl_thread_state_register_pc(thread, dwarf_regs[17]); 43 dwfl_thread_state_register_pc(thread, dwarf_regs[65]);
39 return dwfl_thread_state_registers(thread, 0, 16, dwarf_regs); 44 return dwfl_thread_state_registers(thread, 0, 16, dwarf_regs);
40} 45}