提交 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 {
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_R20,
PERF_REG_SW64_R21,
......@@ -30,16 +33,9 @@ enum perf_event_sw64_regs {
PERF_REG_SW64_R26,
PERF_REG_SW64_R27,
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_R16,
PERF_REG_SW64_R17,
PERF_REG_SW64_R18,
PERF_REG_SW64_SP,
PERF_REG_SW64_PC,
PERF_REG_SW64_MAX,
};
#endif /* _UAPI_ASM_SW64_PERF_REGS_H */
......@@ -13,6 +13,16 @@ enum perf_event_sw64_regs {
PERF_REG_SW64_R6,
PERF_REG_SW64_R7,
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_R20,
PERF_REG_SW64_R21,
......@@ -23,16 +33,9 @@ enum perf_event_sw64_regs {
PERF_REG_SW64_R26,
PERF_REG_SW64_R27,
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_R16,
PERF_REG_SW64_R17,
PERF_REG_SW64_R18,
PERF_REG_SW64_SP,
PERF_REG_SW64_PC,
PERF_REG_SW64_MAX,
};
#endif /* _ASM_SW64_PERF_REGS_H */
......@@ -13,13 +13,75 @@ void perf_regs_load(u64 *regs);
#define PERF_SAMPLE_REGS_ABI PERF_SAMPLE_REGS_ABI_64
#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)
{
switch (id) {
case PERF_REG_SW64_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:
return NULL;
}
......
......@@ -25,7 +25,7 @@ static int sample_ustack(struct perf_sample *sample,
return -1;
}
sp = (unsigned long) regs[30];
sp = (unsigned long) regs[PERF_REG_SW64_SP];
map = maps__find(thread->maps, (u64)sp);
if (!map) {
......
......@@ -4,35 +4,44 @@
.text
.set noat
.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)
stl $0, 0x0($16);
stl $1, 0x8($16);
stl $2, 0x10($16);
stl $3, 0x18($16);
stl $4, 0x20($16);
stl $5, 0x28($16);
stl $6, 0x30($16);
stl $7, 0x38($16);
stl $8, 0x40($16);
stl $19, 0x48($16);
stl $20, 0x50($16);
stl $21, 0x58($16);
stl $22, 0x60($16);
stl $23, 0x68($16);
stl $24, 0x70($16);
stl $25, 0x78($16);
stl $26, 0x80($16);
stl $27, 0x88($16);
stl $28, 0x90($16);
stl $30, 0x98($16);
stl $20, 0xa0($16);
stl $21, 0xa8($16);
stl $22, 0xb0($16);
stl $23, 0xb8($16);
stl $26, 0xc0($16);
stl $29, 0xc8($16);
stl $16, 0xd0($16);
stl $17, 0xd8($16);
stl $18, 0xe0($16);
STL_REG(0)
STL_REG(1)
STL_REG(2)
STL_REG(3)
STL_REG(4)
STL_REG(5)
STL_REG(6)
STL_REG(7)
STL_REG(8)
STL_REG(9)
STL_REG(10)
STL_REG(11)
STL_REG(12)
STL_REG(13)
STL_REG(14)
STL_REG(15)
STL_REG(16)
STL_REG(17)
STL_REG(18)
STL_REG(19)
STL_REG(20)
STL_REG(21)
STL_REG(22)
STL_REG(23)
STL_REG(24)
STL_REG(25)
STL_REG(26)
STL_REG(27)
STL_REG(28)
STL_REG(29)
mov $30, $17
stl $17, (SP)($16)
stl $26, (PC)($16)
LDL_REG(17)
ret
SYM_FUNC_END(perf_regs_load)
......@@ -23,41 +23,45 @@ struct pt_regs_dwarfnum {
};
#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 DWARFNUM2OFFSET(index) \
(index * sizeof((struct user_pt_regs *)0)->regs[0])
static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
REG_DWARFNUM_NAME("%v0", 0),
REG_DWARFNUM_NAME("%t0", 1),
REG_DWARFNUM_NAME("%t1", 2),
REG_DWARFNUM_NAME("%t2", 3),
REG_DWARFNUM_NAME("%t3", 4),
REG_DWARFNUM_NAME("%t4", 5),
REG_DWARFNUM_NAME("%t5", 6),
REG_DWARFNUM_NAME("%t6", 7),
REG_DWARFNUM_NAME("%t7", 8),
REG_DWARFNUM_NAME("%s0", 9),
REG_DWARFNUM_NAME("%s1", 10),
REG_DWARFNUM_NAME("%s2", 11),
REG_DWARFNUM_NAME("%s3", 12),
REG_DWARFNUM_NAME("%s4", 13),
REG_DWARFNUM_NAME("%s5", 14),
REG_DWARFNUM_NAME("%s6", 15),
REG_DWARFNUM_NAME("%a0", 16),
REG_DWARFNUM_NAME("%a1", 17),
REG_DWARFNUM_NAME("%a2", 18),
REG_DWARFNUM_NAME("%a3", 19),
REG_DWARFNUM_NAME("%a4", 20),
REG_DWARFNUM_NAME("%a5", 21),
REG_DWARFNUM_NAME("%t8", 22),
REG_DWARFNUM_NAME("%t9", 23),
REG_DWARFNUM_NAME("%t10", 24),
REG_DWARFNUM_NAME("%t11", 25),
REG_DWARFNUM_NAME("%ra", 26),
REG_DWARFNUM_NAME("%pv", 27),
REG_DWARFNUM_NAME("%at", 28),
GPR_DWARFNUM_NAME(0),
GPR_DWARFNUM_NAME(1),
GPR_DWARFNUM_NAME(2),
GPR_DWARFNUM_NAME(3),
GPR_DWARFNUM_NAME(4),
GPR_DWARFNUM_NAME(5),
GPR_DWARFNUM_NAME(6),
GPR_DWARFNUM_NAME(7),
GPR_DWARFNUM_NAME(8),
GPR_DWARFNUM_NAME(9),
GPR_DWARFNUM_NAME(10),
GPR_DWARFNUM_NAME(11),
GPR_DWARFNUM_NAME(12),
GPR_DWARFNUM_NAME(13),
GPR_DWARFNUM_NAME(14),
GPR_DWARFNUM_NAME(15),
REG_DWARFNUM_NAME("%fp", 15),
GPR_DWARFNUM_NAME(16),
GPR_DWARFNUM_NAME(17),
GPR_DWARFNUM_NAME(18),
GPR_DWARFNUM_NAME(19),
GPR_DWARFNUM_NAME(20),
GPR_DWARFNUM_NAME(21),
GPR_DWARFNUM_NAME(22),
GPR_DWARFNUM_NAME(23),
GPR_DWARFNUM_NAME(24),
GPR_DWARFNUM_NAME(25),
GPR_DWARFNUM_NAME(26),
GPR_DWARFNUM_NAME(27),
GPR_DWARFNUM_NAME(28),
REG_DWARFNUM_NAME("%gp", 29),
REG_DWARFNUM_NAME("%sp", 30),
REG_DWARFNUM_NAME("%zero", 31),
REG_DWARFNUM_END,
};
......@@ -72,7 +76,6 @@ static const struct pt_regs_dwarfnum regdwarfnum_table[] = {
const char *get_arch_regstr(unsigned int n)
{
const struct pt_regs_dwarfnum *roff;
for (roff = regdwarfnum_table; roff->name != NULL; roff++)
if (roff->dwarfnum == n)
return roff->name;
......@@ -85,6 +88,6 @@ int regs_query_register_offset(const char *name)
for (roff = regdwarfnum_table; roff->name != NULL; roff++)
if (!strcmp(roff->name, name))
return roff->dwarfnum;
return DWARFNUM2OFFSET(roff->dwarfnum);
return -EINVAL;
}
......@@ -11,10 +11,68 @@
int LIBUNWIND__ARCH_REG_ID(int 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:
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:
return PERF_REG_SW64_HAE;
return PERF_REG_SW64_SP;
case UNW_SW_64_PC:
return PERF_REG_SW64_PC;
default:
......
......@@ -17,9 +17,9 @@
/* Define arch specific functions & regs for libunwind, should be
* 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_SP PERF_REG_SW64_HAE
#define LIBUNWIND__ARCH_REG_SP PERF_REG_SW64_SP
#include "unwind.h"
#include "debug.h"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册