Commit e7c0219b authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

objtool: Fix !CFI insn_state propagation



Objtool keeps per instruction CFI state in struct insn_state and will
save/restore this where required. However, insn_state has grown some
!CFI state, and this must not be saved/restored (that would
loose/destroy state).

Fix this by moving the CFI specific parts of insn_state into struct
cfi_state.

Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: default avatarMiroslav Benes <mbenes@suse.cz>
Reviewed-by: default avatarAlexandre Chartre <alexandre.chartre@oracle.com>
Acked-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Link: https://lkml.kernel.org/r/20200416115119.045821071@infradead.org


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent a3608f59
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -19,8 +19,20 @@ struct cfi_reg {
};

struct cfi_init_state {
	struct cfi_reg regs[CFI_NUM_REGS];
	struct cfi_reg cfa;
};

struct cfi_state {
	struct cfi_reg regs[CFI_NUM_REGS];
	struct cfi_reg vals[CFI_NUM_REGS];
	struct cfi_reg cfa;
	int stack_size;
	int drap_reg, drap_offset;
	unsigned char type;
	bool bp_scratch;
	bool drap;
	bool end;
};

#endif /* _OBJTOOL_CFI_H */
+137 −127

File changed.

Preview size limit exceeded, changes collapsed.

+4 −9
Original line number Diff line number Diff line
@@ -14,15 +14,10 @@
#include <linux/hashtable.h>

struct insn_state {
	struct cfi_reg cfa;
	struct cfi_reg regs[CFI_NUM_REGS];
	int stack_size;
	unsigned char type;
	bool bp_scratch;
	bool drap, end, uaccess, df;
	struct cfi_state cfi;
	unsigned int uaccess_stack;
	int drap_reg, drap_offset;
	struct cfi_reg vals[CFI_NUM_REGS];
	bool uaccess;
	bool df;
};

struct instruction {
@@ -45,7 +40,7 @@ struct instruction {
	struct list_head alts;
	struct symbol *func;
	struct list_head stack_ops;
	struct insn_state state;
	struct cfi_state cfi;
	struct orc_entry orc;
};

+4 −4
Original line number Diff line number Diff line
@@ -16,10 +16,10 @@ int create_orc(struct objtool_file *file)

	for_each_insn(file, insn) {
		struct orc_entry *orc = &insn->orc;
		struct cfi_reg *cfa = &insn->state.cfa;
		struct cfi_reg *bp = &insn->state.regs[CFI_BP];
		struct cfi_reg *cfa = &insn->cfi.cfa;
		struct cfi_reg *bp = &insn->cfi.regs[CFI_BP];

		orc->end = insn->state.end;
		orc->end = insn->cfi.end;

		if (cfa->base == CFI_UNDEFINED) {
			orc->sp_reg = ORC_REG_UNDEFINED;
@@ -75,7 +75,7 @@ int create_orc(struct objtool_file *file)

		orc->sp_offset = cfa->offset;
		orc->bp_offset = bp->offset;
		orc->type = insn->state.type;
		orc->type = insn->cfi.type;
	}

	return 0;