Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

objtool: Make SP memory operation match PUSH/POP semantics

Architectures without PUSH/POP instructions will always access the stack
though memory operations (SRC/DEST_INDIRECT). Make those operations have
the same effect on the CFA as PUSH/POP, with no stack pointer
modification.

Signed-off-by: Julien Thierry <jthierry@redhat.com>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>

authored by

Julien Thierry and committed by
Josh Poimboeuf
201ef5a9 468af56a

+20
+20
tools/objtool/check.c
··· 2065 2065 break; 2066 2066 2067 2067 case OP_SRC_REG_INDIRECT: 2068 + if (!cfi->drap && op->dest.reg == cfa->base && 2069 + op->dest.reg == CFI_BP) { 2070 + 2071 + /* mov disp(%rsp), %rbp */ 2072 + cfa->base = CFI_SP; 2073 + cfa->offset = cfi->stack_size; 2074 + } 2075 + 2068 2076 if (cfi->drap && op->src.reg == CFI_BP && 2069 2077 op->src.offset == cfi->drap_offset) { 2070 2078 ··· 2092 2084 op->src.offset == regs[op->dest.reg].offset + cfa->offset) { 2093 2085 2094 2086 /* mov disp(%rbp), %reg */ 2087 + /* mov disp(%rsp), %reg */ 2088 + restore_reg(cfi, op->dest.reg); 2089 + 2090 + } else if (op->src.reg == CFI_SP && 2091 + op->src.offset == regs[op->dest.reg].offset + cfi->stack_size) { 2092 + 2095 2093 /* mov disp(%rsp), %reg */ 2096 2094 restore_reg(cfi, op->dest.reg); 2097 2095 } ··· 2177 2163 /* mov reg, disp(%rsp) */ 2178 2164 save_reg(cfi, op->src.reg, CFI_CFA, 2179 2165 op->dest.offset - cfi->cfa.offset); 2166 + 2167 + } else if (op->dest.reg == CFI_SP) { 2168 + 2169 + /* mov reg, disp(%rsp) */ 2170 + save_reg(cfi, op->src.reg, CFI_CFA, 2171 + op->dest.offset - cfi->stack_size); 2180 2172 } 2181 2173 2182 2174 break;