Skip to content

Commit 49c1398

Browse files
authored
Merge pull request #42 from angrq/master
PPC64 support. Stumbled upon a minor bug in kallsym lookup.
2 parents 53cd6c4 + b720233 commit 49c1398

File tree

3 files changed

+145
-1
lines changed

3 files changed

+145
-1
lines changed

src/libply/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ EXTRA_DIST = grammar.c grammar.h lexer.c lexer.h \
1313
arch/loongarch64.c \
1414
arch/mips.c \
1515
arch/powerpc.c \
16+
arch/powerpc64.c \
1617
arch/riscv32.c \
1718
arch/riscv64.c \
1819
arch/x86_64.c

src/libply/arch/powerpc64.c

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
/*
2+
* Copyright Tobias Waldekranz <tobias@waldekranz.com>
3+
*
4+
* SPDX-License-Identifier: GPL-2.0
5+
*/
6+
7+
#include <assert.h>
8+
9+
#include <ply/internal.h>
10+
11+
#define arch_typedef(_a, _t) { \
12+
.ttype = T_TYPEDEF, \
13+
.tdef = { .name = #_a, .type = _t }, \
14+
}
15+
16+
struct type t_s8 = arch_typedef(s8, &t_schar);
17+
struct type t_u8 = arch_typedef(u8, &t_uchar);
18+
struct type t_s16 = arch_typedef(s16, &t_sshort);
19+
struct type t_u16 = arch_typedef(u16, &t_ushort);
20+
struct type t_s32 = arch_typedef(s32, &t_sint);
21+
struct type t_u32 = arch_typedef(u32, &t_uint);
22+
struct type t_s64 = arch_typedef(s64, &t_slong);
23+
struct type t_u64 = arch_typedef(u64, &t_ulong);
24+
25+
static int reg_fprint(struct type *t, FILE *fp, const void *data)
26+
{
27+
return fprintf(fp, "%#lx", *((unsigned long *)data));
28+
}
29+
30+
struct type t_reg_t = {
31+
.ttype = T_TYPEDEF,
32+
.tdef = {
33+
.name = "reg_t",
34+
.type = &t_ulong,
35+
},
36+
37+
.fprint = reg_fprint,
38+
};
39+
40+
struct tfield f_pt_regs_fields[] = {
41+
{ .name = "gpr0", .type = &t_reg_t },
42+
{ .name = "gpr1", .type = &t_reg_t },
43+
{ .name = "gpr2", .type = &t_reg_t },
44+
{ .name = "gpr3", .type = &t_reg_t },
45+
{ .name = "gpr4", .type = &t_reg_t },
46+
{ .name = "gpr5", .type = &t_reg_t },
47+
{ .name = "gpr6", .type = &t_reg_t },
48+
{ .name = "gpr7", .type = &t_reg_t },
49+
{ .name = "gpr8", .type = &t_reg_t },
50+
{ .name = "gpr9", .type = &t_reg_t },
51+
{ .name = "gpr10", .type = &t_reg_t },
52+
{ .name = "gpr11", .type = &t_reg_t },
53+
{ .name = "gpr12", .type = &t_reg_t },
54+
{ .name = "gpr13", .type = &t_reg_t },
55+
{ .name = "gpr14", .type = &t_reg_t },
56+
{ .name = "gpr15", .type = &t_reg_t },
57+
{ .name = "gpr16", .type = &t_reg_t },
58+
{ .name = "gpr17", .type = &t_reg_t },
59+
{ .name = "gpr18", .type = &t_reg_t },
60+
{ .name = "gpr19", .type = &t_reg_t },
61+
{ .name = "gpr20", .type = &t_reg_t },
62+
{ .name = "gpr12", .type = &t_reg_t },
63+
{ .name = "gpr22", .type = &t_reg_t },
64+
{ .name = "gpr23", .type = &t_reg_t },
65+
{ .name = "gpr24", .type = &t_reg_t },
66+
{ .name = "gpr25", .type = &t_reg_t },
67+
{ .name = "gpr26", .type = &t_reg_t },
68+
{ .name = "gpr27", .type = &t_reg_t },
69+
{ .name = "gpr28", .type = &t_reg_t },
70+
{ .name = "gpr29", .type = &t_reg_t },
71+
{ .name = "gpr30", .type = &t_reg_t },
72+
{ .name = "gpr31", .type = &t_reg_t },
73+
{ .name = "nip", .type = &t_reg_t },
74+
{ .name = "msr", .type = &t_reg_t },
75+
{ .name = "orig_gpr3", .type = &t_reg_t },
76+
{ .name = "ctr", .type = &t_reg_t },
77+
{ .name = "link", .type = &t_reg_t },
78+
{ .name = "xer", .type = &t_reg_t },
79+
{ .name = "ccr", .type = &t_reg_t },
80+
{ .name = "softe", .type = &t_reg_t },
81+
{ .name = "trap", .type = &t_reg_t },
82+
{ .name = "dar", .type = &t_reg_t },
83+
{ .name = "dsisr", .type = &t_reg_t },
84+
{ .name = "result", .type = &t_reg_t },
85+
86+
{ .type = NULL }
87+
};
88+
89+
struct type t_pt_regs = {
90+
.ttype = T_STRUCT,
91+
92+
.sou = {
93+
.name = "pt_regs",
94+
.fields = f_pt_regs_fields,
95+
},
96+
};
97+
98+
struct type *arch_types[] = {
99+
&t_s8, &t_u8,
100+
&t_s16, &t_u16,
101+
&t_s32, &t_u32,
102+
&t_s64, &t_u64,
103+
&t_reg_t, &t_pt_regs,
104+
105+
NULL
106+
};
107+
108+
const char *arch_register_argument(int num)
109+
{
110+
switch (num) {
111+
case 0: return "gpr3";
112+
case 1: return "gpr4";
113+
case 2: return "gpr5";
114+
case 3: return "gpr6";
115+
case 4: return "gpr7";
116+
case 5: return "gpr8";
117+
case 6: return "gpr9";
118+
}
119+
120+
return NULL;
121+
}
122+
123+
const char *arch_register_pc(void)
124+
{
125+
return "nip";
126+
}
127+
128+
const char *arch_register_return(void)
129+
{
130+
return "gpr3";
131+
}
132+
133+
__attribute__((constructor))
134+
static void arch_init(void)
135+
{
136+
type_struct_layout(&t_pt_regs);
137+
type_add_list(arch_types);
138+
}

src/libply/aux/kallsyms.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,12 @@ static int ksym_sort_cmp(const void *_a, const void *_b)
223223
{
224224
const struct ksym *a = _a, *b = _b;
225225

226-
return a->addr - b->addr;
226+
if (a->addr > b->addr)
227+
return 1;
228+
else if (a->addr < b->addr)
229+
return -1;
230+
else
231+
return 0;
227232
}
228233

229234
static int ksyms_cache_sort(struct ksyms *ks)

0 commit comments

Comments
 (0)