提交 58b964b3 编写于 作者: H He Chuyue 提交者: guzitao

sw64: perf: fix support for dwarf in perf

Sunway inclusion
category: feature
bugzilla: https://gitee.com/openeuler/kernel/issues/I56X48

--------------------------------

This patch:
  - Fix the corresponding labels in kernel and perf according to the
    integer register sorting in libunwind.
  - Fix wrong stl and format styles in regs_load.S test program.

Now, we can pass perf test: dwarf.
Signed-off-by: NHe Chuyue <hechuyue@wxiat.com>
Reviewed-by: NHe Sheng <hesheng@wxiat.com>
Signed-off-by: NGu Zitao <guzitao@wxiat.com>
上级 86884051
...@@ -20,6 +20,9 @@ enum perf_event_sw64_regs { ...@@ -20,6 +20,9 @@ enum perf_event_sw64_regs {
PERF_REG_SW64_R13, PERF_REG_SW64_R13,
PERF_REG_SW64_R14, PERF_REG_SW64_R14,
PERF_REG_SW64_R15, PERF_REG_SW64_R15,
PERF_REG_SW64_R16,
PERF_REG_SW64_R17,
PERF_REG_SW64_R18,
PERF_REG_SW64_R19, PERF_REG_SW64_R19,
PERF_REG_SW64_R20, PERF_REG_SW64_R20,
PERF_REG_SW64_R21, PERF_REG_SW64_R21,
...@@ -30,16 +33,9 @@ enum perf_event_sw64_regs { ...@@ -30,16 +33,9 @@ enum perf_event_sw64_regs {
PERF_REG_SW64_R26, PERF_REG_SW64_R26,
PERF_REG_SW64_R27, PERF_REG_SW64_R27,
PERF_REG_SW64_R28, PERF_REG_SW64_R28,
PERF_REG_SW64_HAE,
PERF_REG_SW64_TRAP_A0,
PERF_REG_SW64_TRAP_A1,
PERF_REG_SW64_TRAP_A2,
PERF_REG_SW64_PS,
PERF_REG_SW64_PC,
PERF_REG_SW64_GP, PERF_REG_SW64_GP,
PERF_REG_SW64_R16, PERF_REG_SW64_SP,
PERF_REG_SW64_R17, PERF_REG_SW64_PC,
PERF_REG_SW64_R18,
PERF_REG_SW64_MAX, PERF_REG_SW64_MAX,
}; };
#endif /* _UAPI_ASM_SW64_PERF_REGS_H */ #endif /* _UAPI_ASM_SW64_PERF_REGS_H */
...@@ -13,6 +13,16 @@ enum perf_event_sw64_regs { ...@@ -13,6 +13,16 @@ enum perf_event_sw64_regs {
PERF_REG_SW64_R6, PERF_REG_SW64_R6,
PERF_REG_SW64_R7, PERF_REG_SW64_R7,
PERF_REG_SW64_R8, PERF_REG_SW64_R8,
PERF_REG_SW64_R9,
PERF_REG_SW64_R10,
PERF_REG_SW64_R11,
PERF_REG_SW64_R12,
PERF_REG_SW64_R13,
PERF_REG_SW64_R14,
PERF_REG_SW64_R15,
PERF_REG_SW64_R16,
PERF_REG_SW64_R17,
PERF_REG_SW64_R18,
PERF_REG_SW64_R19, PERF_REG_SW64_R19,
PERF_REG_SW64_R20, PERF_REG_SW64_R20,
PERF_REG_SW64_R21, PERF_REG_SW64_R21,
...@@ -23,16 +33,9 @@ enum perf_event_sw64_regs { ...@@ -23,16 +33,9 @@ enum perf_event_sw64_regs {
PERF_REG_SW64_R26, PERF_REG_SW64_R26,
PERF_REG_SW64_R27, PERF_REG_SW64_R27,
PERF_REG_SW64_R28, PERF_REG_SW64_R28,
PERF_REG_SW64_HAE,
PERF_REG_SW64_TRAP_A0,
PERF_REG_SW64_TRAP_A1,
PERF_REG_SW64_TRAP_A2,
PERF_REG_SW64_PS,
PERF_REG_SW64_PC,
PERF_REG_SW64_GP, PERF_REG_SW64_GP,
PERF_REG_SW64_R16, PERF_REG_SW64_SP,
PERF_REG_SW64_R17, PERF_REG_SW64_PC,
PERF_REG_SW64_R18,
PERF_REG_SW64_MAX, PERF_REG_SW64_MAX,
}; };
#endif /* _ASM_SW64_PERF_REGS_H */ #endif /* _ASM_SW64_PERF_REGS_H */
...@@ -13,13 +13,75 @@ void perf_regs_load(u64 *regs); ...@@ -13,13 +13,75 @@ void perf_regs_load(u64 *regs);
#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64 #define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64
#define PERF_REG_IP PERF_REG_SW64_PC #define PERF_REG_IP PERF_REG_SW64_PC
#define PERF_REG_SP PERF_REG_SW64_HAE #define PERF_REG_SP PERF_REG_SW64_SP
static inline const char *perf_reg_name(int id) static inline const char *perf_reg_name(int id)
{ {
switch (id) { switch (id) {
case PERF_REG_SW64_R0: case PERF_REG_SW64_R0:
return "r0"; return "r0";
case PERF_REG_SW64_R1:
return "r1";
case PERF_REG_SW64_R2:
return "r2";
case PERF_REG_SW64_R3:
return "r3";
case PERF_REG_SW64_R4:
return "r4";
case PERF_REG_SW64_R5:
return "r5";
case PERF_REG_SW64_R6:
return "r6";
case PERF_REG_SW64_R7:
return "r7";
case PERF_REG_SW64_R8:
return "r8";
case PERF_REG_SW64_R9:
return "r9";
case PERF_REG_SW64_R10:
return "r10";
case PERF_REG_SW64_R11:
return "r11";
case PERF_REG_SW64_R12:
return "r12";
case PERF_REG_SW64_R13:
return "r13";
case PERF_REG_SW64_R14:
return "r14";
case PERF_REG_SW64_R15:
return "r15";
case PERF_REG_SW64_R16:
return "r16";
case PERF_REG_SW64_R17:
return "r17";
case PERF_REG_SW64_R18:
return "r18";
case PERF_REG_SW64_R19:
return "r19";
case PERF_REG_SW64_R20:
return "r20";
case PERF_REG_SW64_R21:
return "r21";
case PERF_REG_SW64_R22:
return "r22";
case PERF_REG_SW64_R23:
return "r23";
case PERF_REG_SW64_R24:
return "r24";
case PERF_REG_SW64_R25:
return "r25";
case PERF_REG_SW64_R26:
return "r26";
case PERF_REG_SW64_R27:
return "r27";
case PERF_REG_SW64_R28:
return "r28";
case PERF_REG_SW64_GP:
return "gp";
case PERF_REG_SW64_SP:
return "sp";
case PERF_REG_SW64_PC:
return "pc";
default: default:
return NULL; return NULL;
} }
......
...@@ -25,7 +25,7 @@ static int sample_ustack(struct perf_sample *sample, ...@@ -25,7 +25,7 @@ static int sample_ustack(struct perf_sample *sample,
return -1; return -1;
} }
sp = (unsigned long) regs[30]; sp = (unsigned long) regs[PERF_REG_SW64_SP];
map = maps__find(thread->maps, (u64)sp); map = maps__find(thread->maps, (u64)sp);
if (!map) { if (!map) {
......
...@@ -4,35 +4,44 @@ ...@@ -4,35 +4,44 @@
.text .text
.set noat .set noat
.type perf_regs_load,%function .type perf_regs_load,%function
#define STL_REG(r) stl $r, (8 * r)($16)
#define LDL_REG(r) ldl $r, (8 * r)($16)
#define SP (8 * 30)
#define PC (8 * 31)
SYM_FUNC_START(perf_regs_load) SYM_FUNC_START(perf_regs_load)
stl $0, 0x0($16); STL_REG(0)
stl $1, 0x8($16); STL_REG(1)
stl $2, 0x10($16); STL_REG(2)
stl $3, 0x18($16); STL_REG(3)
stl $4, 0x20($16); STL_REG(4)
stl $5, 0x28($16); STL_REG(5)
stl $6, 0x30($16); STL_REG(6)
stl $7, 0x38($16); STL_REG(7)
stl $8, 0x40($16); STL_REG(8)
stl $19, 0x48($16); STL_REG(9)
stl $20, 0x50($16); STL_REG(10)
stl $21, 0x58($16); STL_REG(11)
stl $22, 0x60($16); STL_REG(12)
stl $23, 0x68($16); STL_REG(13)
stl $24, 0x70($16); STL_REG(14)
stl $25, 0x78($16); STL_REG(15)
stl $26, 0x80($16); STL_REG(16)
stl $27, 0x88($16); STL_REG(17)
stl $28, 0x90($16); STL_REG(18)
stl $30, 0x98($16); STL_REG(19)
stl $20, 0xa0($16); STL_REG(20)
stl $21, 0xa8($16); STL_REG(21)
stl $22, 0xb0($16); STL_REG(22)
stl $23, 0xb8($16); STL_REG(23)
stl $26, 0xc0($16); STL_REG(24)
stl $29, 0xc8($16); STL_REG(25)
stl $16, 0xd0($16); STL_REG(26)
stl $17, 0xd8($16); STL_REG(27)
stl $18, 0xe0($16); STL_REG(28)
STL_REG(29)
mov $30, $17
stl $17, (SP)($16)
stl $26, (PC)($16)
LDL_REG(17)
ret ret
SYM_FUNC_END(perf_regs_load) SYM_FUNC_END(perf_regs_load)
...@@ -23,41 +23,45 @@ struct pt_regs_dwarfnum { ...@@ -23,41 +23,45 @@ struct pt_regs_dwarfnum {
}; };
#define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num} #define REG_DWARFNUM_NAME(r, num) {.name = r, .dwarfnum = num}
#define GPR_DWARFNUM_NAME(num) \
{.name = __stringify(%x##num), .dwarfnum = num}
#define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0} #define REG_DWARFNUM_END {.name = NULL, .dwarfnum = 0}
#define DWARFNUM2OFFSET(index) \
(index * sizeof((struct user_pt_regs *)0)->regs[0])
static const struct pt_regs_dwarfnum regdwarfnum_table[] = { static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
REG_DWARFNUM_NAME("%v0", 0), GPR_DWARFNUM_NAME(0),
REG_DWARFNUM_NAME("%t0", 1), GPR_DWARFNUM_NAME(1),
REG_DWARFNUM_NAME("%t1", 2), GPR_DWARFNUM_NAME(2),
REG_DWARFNUM_NAME("%t2", 3), GPR_DWARFNUM_NAME(3),
REG_DWARFNUM_NAME("%t3", 4), GPR_DWARFNUM_NAME(4),
REG_DWARFNUM_NAME("%t4", 5), GPR_DWARFNUM_NAME(5),
REG_DWARFNUM_NAME("%t5", 6), GPR_DWARFNUM_NAME(6),
REG_DWARFNUM_NAME("%t6", 7), GPR_DWARFNUM_NAME(7),
REG_DWARFNUM_NAME("%t7", 8), GPR_DWARFNUM_NAME(8),
REG_DWARFNUM_NAME("%s0", 9), GPR_DWARFNUM_NAME(9),
REG_DWARFNUM_NAME("%s1", 10), GPR_DWARFNUM_NAME(10),
REG_DWARFNUM_NAME("%s2", 11), GPR_DWARFNUM_NAME(11),
REG_DWARFNUM_NAME("%s3", 12), GPR_DWARFNUM_NAME(12),
REG_DWARFNUM_NAME("%s4", 13), GPR_DWARFNUM_NAME(13),
REG_DWARFNUM_NAME("%s5", 14), GPR_DWARFNUM_NAME(14),
REG_DWARFNUM_NAME("%s6", 15), GPR_DWARFNUM_NAME(15),
REG_DWARFNUM_NAME("%a0", 16), REG_DWARFNUM_NAME("%fp", 15),
REG_DWARFNUM_NAME("%a1", 17), GPR_DWARFNUM_NAME(16),
REG_DWARFNUM_NAME("%a2", 18), GPR_DWARFNUM_NAME(17),
REG_DWARFNUM_NAME("%a3", 19), GPR_DWARFNUM_NAME(18),
REG_DWARFNUM_NAME("%a4", 20), GPR_DWARFNUM_NAME(19),
REG_DWARFNUM_NAME("%a5", 21), GPR_DWARFNUM_NAME(20),
REG_DWARFNUM_NAME("%t8", 22), GPR_DWARFNUM_NAME(21),
REG_DWARFNUM_NAME("%t9", 23), GPR_DWARFNUM_NAME(22),
REG_DWARFNUM_NAME("%t10", 24), GPR_DWARFNUM_NAME(23),
REG_DWARFNUM_NAME("%t11", 25), GPR_DWARFNUM_NAME(24),
REG_DWARFNUM_NAME("%ra", 26), GPR_DWARFNUM_NAME(25),
REG_DWARFNUM_NAME("%pv", 27), GPR_DWARFNUM_NAME(26),
REG_DWARFNUM_NAME("%at", 28), GPR_DWARFNUM_NAME(27),
GPR_DWARFNUM_NAME(28),
REG_DWARFNUM_NAME("%gp", 29), REG_DWARFNUM_NAME("%gp", 29),
REG_DWARFNUM_NAME("%sp", 30), REG_DWARFNUM_NAME("%sp", 30),
REG_DWARFNUM_NAME("%zero", 31),
REG_DWARFNUM_END, REG_DWARFNUM_END,
}; };
...@@ -72,7 +76,6 @@ static const struct pt_regs_dwarfnum regdwarfnum_table[] = { ...@@ -72,7 +76,6 @@ static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
const char *get_arch_regstr(unsigned int n) const char *get_arch_regstr(unsigned int n)
{ {
const struct pt_regs_dwarfnum *roff; const struct pt_regs_dwarfnum *roff;
for (roff = regdwarfnum_table; roff->name != NULL; roff++) for (roff = regdwarfnum_table; roff->name != NULL; roff++)
if (roff->dwarfnum == n) if (roff->dwarfnum == n)
return roff->name; return roff->name;
...@@ -85,6 +88,6 @@ int regs_query_register_offset(const char *name) ...@@ -85,6 +88,6 @@ int regs_query_register_offset(const char *name)
for (roff = regdwarfnum_table; roff->name != NULL; roff++) for (roff = regdwarfnum_table; roff->name != NULL; roff++)
if (!strcmp(roff->name, name)) if (!strcmp(roff->name, name))
return roff->dwarfnum; return DWARFNUM2OFFSET(roff->dwarfnum);
return -EINVAL; return -EINVAL;
} }
...@@ -11,10 +11,68 @@ ...@@ -11,10 +11,68 @@
int LIBUNWIND__ARCH_REG_ID(int regnum) int LIBUNWIND__ARCH_REG_ID(int regnum)
{ {
switch (regnum) { switch (regnum) {
case UNW_SW_64_R0:
return PERF_REG_SW64_R0;
case UNW_SW_64_R1:
return PERF_REG_SW64_R1;
case UNW_SW_64_R2:
return PERF_REG_SW64_R2;
case UNW_SW_64_R3:
return PERF_REG_SW64_R3;
case UNW_SW_64_R4:
return PERF_REG_SW64_R4;
case UNW_SW_64_R5:
return PERF_REG_SW64_R5;
case UNW_SW_64_R6:
return PERF_REG_SW64_R6;
case UNW_SW_64_R7:
return PERF_REG_SW64_R7;
case UNW_SW_64_R8:
return PERF_REG_SW64_R8;
case UNW_SW_64_R9:
return PERF_REG_SW64_R9;
case UNW_SW_64_R10:
return PERF_REG_SW64_R10;
case UNW_SW_64_R11:
return PERF_REG_SW64_R11;
case UNW_SW_64_R12:
return PERF_REG_SW64_R12;
case UNW_SW_64_R13:
return PERF_REG_SW64_R13;
case UNW_SW_64_R14:
return PERF_REG_SW64_R14;
case UNW_SW_64_R15:
return PERF_REG_SW64_R15;
case UNW_SW_64_R16:
return PERF_REG_SW64_R16;
case UNW_SW_64_R17:
return PERF_REG_SW64_R17;
case UNW_SW_64_R18:
return PERF_REG_SW64_R18;
case UNW_SW_64_R19:
return PERF_REG_SW64_R19;
case UNW_SW_64_R20:
return PERF_REG_SW64_R20;
case UNW_SW_64_R21:
return PERF_REG_SW64_R21;
case UNW_SW_64_R22:
return PERF_REG_SW64_R22;
case UNW_SW_64_R23:
return PERF_REG_SW64_R23;
case UNW_SW_64_R24:
return PERF_REG_SW64_R24;
case UNW_SW_64_R25:
return PERF_REG_SW64_R25;
case UNW_SW_64_R26: case UNW_SW_64_R26:
return PERF_REG_SW64_R26; return PERF_REG_SW64_R26;
case UNW_SW_64_R27:
return PERF_REG_SW64_R27;
case UNW_SW_64_R28:
return PERF_REG_SW64_R28;
case UNW_SW_64_R29:
return PERF_REG_SW64_GP;
case UNW_SW_64_R30: case UNW_SW_64_R30:
return PERF_REG_SW64_HAE; return PERF_REG_SW64_SP;
case UNW_SW_64_PC: case UNW_SW_64_PC:
return PERF_REG_SW64_PC; return PERF_REG_SW64_PC;
default: default:
......
...@@ -17,9 +17,9 @@ ...@@ -17,9 +17,9 @@
/* Define arch specific functions & regs for libunwind, should be /* Define arch specific functions & regs for libunwind, should be
* defined before including "unwind.h" * defined before including "unwind.h"
*/ */
#define LIBUNWIND__ARCH_REG_ID(regnum) libunwind__arm64_reg_id(regnum) #define LIBUNWIND__ARCH_REG_ID(regnum) libunwind__sw_64_reg_id(regnum)
#define LIBUNWIND__ARCH_REG_IP PERF_REG_SW64_PC #define LIBUNWIND__ARCH_REG_IP PERF_REG_SW64_PC
#define LIBUNWIND__ARCH_REG_SP PERF_REG_SW64_HAE #define LIBUNWIND__ARCH_REG_SP PERF_REG_SW64_SP
#include "unwind.h" #include "unwind.h"
#include "debug.h" #include "debug.h"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册