diff options
author | Hendrik Brueckner <brueckner@linux.vnet.ibm.com> | 2017-11-08 03:01:12 -0500 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2017-11-16 09:06:13 -0500 |
commit | a9fc2db0a8abf51c81122799c5ae4808f2324b6d (patch) | |
tree | 7327258f0fa6a4e70d87d91c3d1db04faaabcdd6 | |
parent | f704ef44602fbf403e6722c7ed13f62d17e8cb20 (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.h | 71 | ||||
-rw-r--r-- | tools/perf/arch/s390/util/dwarf-regs.c | 15 | ||||
-rw-r--r-- | tools/perf/arch/s390/util/unwind-libdw.c | 15 |
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 | ||
5 | static 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 | */ | ||
11 | static 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 | |||
15 | static 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 | ||
20 | const char *get_arch_regstr(unsigned int n) | 15 | const 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 | ||
7 | bool libdw__arch_set_initial_registers(Dwfl_Thread *thread, void *arg) | 9 | bool 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 | } |