Skip to content

Commit 539d734

Browse files
seehearfeelchenhuacai
authored andcommitted
objtool/LoongArch: Mark special atomic instruction as INSN_BUG type
When compiling with LLVM and CONFIG_RUST is set, there exists the following objtool warning: rust/compiler_builtins.o: warning: objtool: __rust__unordsf2(): unexpected end of section .text.unlikely. objdump shows that the end of section .text.unlikely is an atomic instruction: amswap.w $zero, $ra, $zero According to the LoongArch Reference Manual, if the amswap.w atomic memory access instruction has the same register number as rd and rj, the execution will trigger an Instruction Non-defined Exception, so mark the above instruction as INSN_BUG type to fix the warning. Cc: stable@vger.kernel.org Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent baad783 commit 539d734

File tree

2 files changed

+33
-0
lines changed

2 files changed

+33
-0
lines changed

tools/arch/loongarch/include/asm/inst.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ enum reg2i16_op {
5151
bgeu_op = 0x1b,
5252
};
5353

54+
enum reg3_op {
55+
amswapw_op = 0x70c0,
56+
};
57+
5458
struct reg0i15_format {
5559
unsigned int immediate : 15;
5660
unsigned int opcode : 17;
@@ -96,6 +100,13 @@ struct reg2i16_format {
96100
unsigned int opcode : 6;
97101
};
98102

103+
struct reg3_format {
104+
unsigned int rd : 5;
105+
unsigned int rj : 5;
106+
unsigned int rk : 5;
107+
unsigned int opcode : 17;
108+
};
109+
99110
union loongarch_instruction {
100111
unsigned int word;
101112
struct reg0i15_format reg0i15_format;
@@ -105,6 +116,7 @@ union loongarch_instruction {
105116
struct reg2i12_format reg2i12_format;
106117
struct reg2i14_format reg2i14_format;
107118
struct reg2i16_format reg2i16_format;
119+
struct reg3_format reg3_format;
108120
};
109121

110122
#define LOONGARCH_INSN_SIZE sizeof(union loongarch_instruction)

tools/objtool/arch/loongarch/decode.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,25 @@ static bool decode_insn_reg2i16_fomat(union loongarch_instruction inst,
278278
return true;
279279
}
280280

281+
static bool decode_insn_reg3_fomat(union loongarch_instruction inst,
282+
struct instruction *insn)
283+
{
284+
switch (inst.reg3_format.opcode) {
285+
case amswapw_op:
286+
if (inst.reg3_format.rd == LOONGARCH_GPR_ZERO &&
287+
inst.reg3_format.rk == LOONGARCH_GPR_RA &&
288+
inst.reg3_format.rj == LOONGARCH_GPR_ZERO) {
289+
/* amswap.w $zero, $ra, $zero */
290+
insn->type = INSN_BUG;
291+
}
292+
break;
293+
default:
294+
return false;
295+
}
296+
297+
return true;
298+
}
299+
281300
int arch_decode_instruction(struct objtool_file *file, const struct section *sec,
282301
unsigned long offset, unsigned int maxlen,
283302
struct instruction *insn)
@@ -309,6 +328,8 @@ int arch_decode_instruction(struct objtool_file *file, const struct section *sec
309328
return 0;
310329
if (decode_insn_reg2i16_fomat(inst, insn))
311330
return 0;
331+
if (decode_insn_reg3_fomat(inst, insn))
332+
return 0;
312333

313334
if (inst.word == 0) {
314335
/* andi $zero, $zero, 0x0 */

0 commit comments

Comments
 (0)