[RFC v5 26/57] objtool: arm64: Decode brk instruction

Julien Thierry jthierry at redhat.com
Thu Jan 9 08:02:29 PST 2020


Add decoding brk instructions. Associate known immediate values with
their kernel/compiler semantics.

Suggested-by: Raphael Gault <raphael.gault at arm.com>
Signed-off-by: Julien Thierry <jthierry at redhat.com>
---
 tools/objtool/arch/arm64/decode.c | 33 +++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/tools/objtool/arch/arm64/decode.c b/tools/objtool/arch/arm64/decode.c
index aa00de725686..1609750cc4b9 100644
--- a/tools/objtool/arch/arm64/decode.c
+++ b/tools/objtool/arch/arm64/decode.c
@@ -507,6 +507,7 @@ int arm_decode_except_gen(u32 instr, enum insn_type *type,
 #define INSN_SVC	0b00000001
 #define INSN_HVC	0b00000010
 #define INSN_SMC	0b00000011
+#define INSN_BRK	0b00100000
 
 	switch (decode_field) {
 	case INSN_SVC:
@@ -518,6 +519,38 @@ int arm_decode_except_gen(u32 instr, enum insn_type *type,
 		 */
 		*type = INSN_NOP;
 		return 0;
+	case INSN_BRK:
+		/* Based on arch/arm64/include/asm/brk-imm.h */
+		switch (imm16) {
+		case 0x004: /* KPROBES_BRK_IMM */
+		case 0x005: /* UPROBES_BRK_IMM */
+		case 0x400: /* KGDB_DYN_DBG_BRK_IMM */
+		case 0x401: /* KGDB_COMPILED_DBG_BRK_IMM */
+			*type = INSN_OTHER;
+			break;
+		case 0x800: /* BUG_BRK_IMM */
+			/*
+			 * brk #0x800 is generated by the BUG()/WARN() linux API
+			 * and is thus a particular case. Since those are not
+			 * necessarily compiled in, the surrounding code should
+			 * work properly without it. We thus consider it as a
+			 * nop.
+			 */
+			*type = INSN_NOP;
+			break;
+		case 0x3e8:
+			/*
+			 * Similar to the use of "ud2" on x86, GCC inserts
+			 * "brk #0x38e" instructions for certain divide-by-zero
+			 * cases.
+			 */
+			*type = INSN_BUG;
+			break;
+		default:
+			*type = INSN_CONTEXT_SWITCH;
+			break;
+		}
+		return 0;
 	default:
 		return arm_decode_unknown(instr, type, immediate, ops_list);
 	}
-- 
2.21.0




More information about the linux-arm-kernel mailing list