Skip to content

Commit b8e85e6

Browse files
seehearfeelchenhuacai
authored andcommitted
objtool/x86: Separate arch-specific and generic parts
Move init_orc_entry(), write_orc_entry(), reg_name(), orc_type_name() and print_reg() from generic orc_gen.c and orc_dump.c to arch-specific orc.c, then introduce a new function orc_print_dump() to print info. This is preparation for later patch, no functionality change. Co-developed-by: Jinyang He <hejinyang@loongson.cn> Signed-off-by: Jinyang He <hejinyang@loongson.cn> Co-developed-by: Youling Tang <tangyouling@loongson.cn> Signed-off-by: Youling Tang <tangyouling@loongson.cn> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent b2d2315 commit b8e85e6

File tree

5 files changed

+206
-179
lines changed

5 files changed

+206
-179
lines changed

tools/objtool/arch/x86/Build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
objtool-y += special.o
22
objtool-y += decode.o
3+
objtool-y += orc.o
34

45
inat_tables_script = ../arch/x86/tools/gen-insn-attr-x86.awk
56
inat_tables_maps = ../arch/x86/lib/x86-opcode-map.txt

tools/objtool/arch/x86/orc.c

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
#include <linux/objtool_types.h>
3+
#include <asm/orc_types.h>
4+
5+
#include <objtool/check.h>
6+
#include <objtool/orc.h>
7+
#include <objtool/warn.h>
8+
#include <objtool/endianness.h>
9+
10+
int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, struct instruction *insn)
11+
{
12+
struct cfi_reg *bp = &cfi->regs[CFI_BP];
13+
14+
memset(orc, 0, sizeof(*orc));
15+
16+
if (!cfi) {
17+
/*
18+
* This is usually either unreachable nops/traps (which don't
19+
* trigger unreachable instruction warnings), or
20+
* STACK_FRAME_NON_STANDARD functions.
21+
*/
22+
orc->type = ORC_TYPE_UNDEFINED;
23+
return 0;
24+
}
25+
26+
switch (cfi->type) {
27+
case UNWIND_HINT_TYPE_UNDEFINED:
28+
orc->type = ORC_TYPE_UNDEFINED;
29+
return 0;
30+
case UNWIND_HINT_TYPE_END_OF_STACK:
31+
orc->type = ORC_TYPE_END_OF_STACK;
32+
return 0;
33+
case UNWIND_HINT_TYPE_CALL:
34+
orc->type = ORC_TYPE_CALL;
35+
break;
36+
case UNWIND_HINT_TYPE_REGS:
37+
orc->type = ORC_TYPE_REGS;
38+
break;
39+
case UNWIND_HINT_TYPE_REGS_PARTIAL:
40+
orc->type = ORC_TYPE_REGS_PARTIAL;
41+
break;
42+
default:
43+
WARN_INSN(insn, "unknown unwind hint type %d", cfi->type);
44+
return -1;
45+
}
46+
47+
orc->signal = cfi->signal;
48+
49+
switch (cfi->cfa.base) {
50+
case CFI_SP:
51+
orc->sp_reg = ORC_REG_SP;
52+
break;
53+
case CFI_SP_INDIRECT:
54+
orc->sp_reg = ORC_REG_SP_INDIRECT;
55+
break;
56+
case CFI_BP:
57+
orc->sp_reg = ORC_REG_BP;
58+
break;
59+
case CFI_BP_INDIRECT:
60+
orc->sp_reg = ORC_REG_BP_INDIRECT;
61+
break;
62+
case CFI_R10:
63+
orc->sp_reg = ORC_REG_R10;
64+
break;
65+
case CFI_R13:
66+
orc->sp_reg = ORC_REG_R13;
67+
break;
68+
case CFI_DI:
69+
orc->sp_reg = ORC_REG_DI;
70+
break;
71+
case CFI_DX:
72+
orc->sp_reg = ORC_REG_DX;
73+
break;
74+
default:
75+
WARN_INSN(insn, "unknown CFA base reg %d", cfi->cfa.base);
76+
return -1;
77+
}
78+
79+
switch (bp->base) {
80+
case CFI_UNDEFINED:
81+
orc->bp_reg = ORC_REG_UNDEFINED;
82+
break;
83+
case CFI_CFA:
84+
orc->bp_reg = ORC_REG_PREV_SP;
85+
break;
86+
case CFI_BP:
87+
orc->bp_reg = ORC_REG_BP;
88+
break;
89+
default:
90+
WARN_INSN(insn, "unknown BP base reg %d", bp->base);
91+
return -1;
92+
}
93+
94+
orc->sp_offset = cfi->cfa.offset;
95+
orc->bp_offset = bp->offset;
96+
97+
return 0;
98+
}
99+
100+
int write_orc_entry(struct elf *elf, struct section *orc_sec,
101+
struct section *ip_sec, unsigned int idx,
102+
struct section *insn_sec, unsigned long insn_off,
103+
struct orc_entry *o)
104+
{
105+
struct orc_entry *orc;
106+
107+
/* populate ORC data */
108+
orc = (struct orc_entry *)orc_sec->data->d_buf + idx;
109+
memcpy(orc, o, sizeof(*orc));
110+
orc->sp_offset = bswap_if_needed(elf, orc->sp_offset);
111+
orc->bp_offset = bswap_if_needed(elf, orc->bp_offset);
112+
113+
/* populate reloc for ip */
114+
if (!elf_init_reloc_text_sym(elf, ip_sec, idx * sizeof(int), idx,
115+
insn_sec, insn_off))
116+
return -1;
117+
118+
return 0;
119+
}
120+
121+
static const char *reg_name(unsigned int reg)
122+
{
123+
switch (reg) {
124+
case ORC_REG_PREV_SP:
125+
return "prevsp";
126+
case ORC_REG_DX:
127+
return "dx";
128+
case ORC_REG_DI:
129+
return "di";
130+
case ORC_REG_BP:
131+
return "bp";
132+
case ORC_REG_SP:
133+
return "sp";
134+
case ORC_REG_R10:
135+
return "r10";
136+
case ORC_REG_R13:
137+
return "r13";
138+
case ORC_REG_BP_INDIRECT:
139+
return "bp(ind)";
140+
case ORC_REG_SP_INDIRECT:
141+
return "sp(ind)";
142+
default:
143+
return "?";
144+
}
145+
}
146+
147+
static const char *orc_type_name(unsigned int type)
148+
{
149+
switch (type) {
150+
case ORC_TYPE_UNDEFINED:
151+
return "(und)";
152+
case ORC_TYPE_END_OF_STACK:
153+
return "end";
154+
case ORC_TYPE_CALL:
155+
return "call";
156+
case ORC_TYPE_REGS:
157+
return "regs";
158+
case ORC_TYPE_REGS_PARTIAL:
159+
return "regs (partial)";
160+
default:
161+
return "?";
162+
}
163+
}
164+
165+
static void print_reg(unsigned int reg, int offset)
166+
{
167+
if (reg == ORC_REG_BP_INDIRECT)
168+
printf("(bp%+d)", offset);
169+
else if (reg == ORC_REG_SP_INDIRECT)
170+
printf("(sp)%+d", offset);
171+
else if (reg == ORC_REG_UNDEFINED)
172+
printf("(und)");
173+
else
174+
printf("%s%+d", reg_name(reg), offset);
175+
}
176+
177+
void orc_print_dump(struct elf *dummy_elf, struct orc_entry *orc, int i)
178+
{
179+
printf("type:%s", orc_type_name(orc[i].type));
180+
181+
printf(" sp:");
182+
print_reg(orc[i].sp_reg, bswap_if_needed(dummy_elf, orc[i].sp_offset));
183+
184+
printf(" bp:");
185+
print_reg(orc[i].bp_reg, bswap_if_needed(dummy_elf, orc[i].bp_offset));
186+
187+
printf(" signal:%d\n", orc[i].signal);
188+
}

tools/objtool/include/objtool/orc.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
#ifndef _OBJTOOL_ORC_H
3+
#define _OBJTOOL_ORC_H
4+
5+
#include <objtool/check.h>
6+
7+
int init_orc_entry(struct orc_entry *orc, struct cfi_state *cfi, struct instruction *insn);
8+
void orc_print_dump(struct elf *dummy_elf, struct orc_entry *orc, int i);
9+
int write_orc_entry(struct elf *elf, struct section *orc_sec,
10+
struct section *ip_sec, unsigned int idx,
11+
struct section *insn_sec, unsigned long insn_off,
12+
struct orc_entry *o);
13+
14+
#endif /* _OBJTOOL_ORC_H */

tools/objtool/orc_dump.c

Lines changed: 2 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -6,65 +6,10 @@
66
#include <unistd.h>
77
#include <asm/orc_types.h>
88
#include <objtool/objtool.h>
9+
#include <objtool/orc.h>
910
#include <objtool/warn.h>
1011
#include <objtool/endianness.h>
1112

12-
static const char *reg_name(unsigned int reg)
13-
{
14-
switch (reg) {
15-
case ORC_REG_PREV_SP:
16-
return "prevsp";
17-
case ORC_REG_DX:
18-
return "dx";
19-
case ORC_REG_DI:
20-
return "di";
21-
case ORC_REG_BP:
22-
return "bp";
23-
case ORC_REG_SP:
24-
return "sp";
25-
case ORC_REG_R10:
26-
return "r10";
27-
case ORC_REG_R13:
28-
return "r13";
29-
case ORC_REG_BP_INDIRECT:
30-
return "bp(ind)";
31-
case ORC_REG_SP_INDIRECT:
32-
return "sp(ind)";
33-
default:
34-
return "?";
35-
}
36-
}
37-
38-
static const char *orc_type_name(unsigned int type)
39-
{
40-
switch (type) {
41-
case ORC_TYPE_UNDEFINED:
42-
return "(und)";
43-
case ORC_TYPE_END_OF_STACK:
44-
return "end";
45-
case ORC_TYPE_CALL:
46-
return "call";
47-
case ORC_TYPE_REGS:
48-
return "regs";
49-
case ORC_TYPE_REGS_PARTIAL:
50-
return "regs (partial)";
51-
default:
52-
return "?";
53-
}
54-
}
55-
56-
static void print_reg(unsigned int reg, int offset)
57-
{
58-
if (reg == ORC_REG_BP_INDIRECT)
59-
printf("(bp%+d)", offset);
60-
else if (reg == ORC_REG_SP_INDIRECT)
61-
printf("(sp)%+d", offset);
62-
else if (reg == ORC_REG_UNDEFINED)
63-
printf("(und)");
64-
else
65-
printf("%s%+d", reg_name(reg), offset);
66-
}
67-
6813
int orc_dump(const char *_objname)
6914
{
7015
int fd, nr_entries, i, *orc_ip = NULL, orc_size = 0;
@@ -205,17 +150,7 @@ int orc_dump(const char *_objname)
205150
printf("%llx:", (unsigned long long)(orc_ip_addr + (i * sizeof(int)) + orc_ip[i]));
206151
}
207152

208-
printf("type:%s", orc_type_name(orc[i].type));
209-
210-
printf(" sp:");
211-
212-
print_reg(orc[i].sp_reg, bswap_if_needed(&dummy_elf, orc[i].sp_offset));
213-
214-
printf(" bp:");
215-
216-
print_reg(orc[i].bp_reg, bswap_if_needed(&dummy_elf, orc[i].bp_offset));
217-
218-
printf(" signal:%d\n", orc[i].signal);
153+
orc_print_dump(&dummy_elf, orc, i);
219154
}
220155

221156
elf_end(elf);

0 commit comments

Comments
 (0)