Skip to content

Commit

Permalink
Merge tag 'objtool-core-2021-02-23' of git://git.kernel.org/pub/scm/l…
Browse files Browse the repository at this point in the history
…inux/kernel/git/tip/tip

Pull objtool updates from Thomas Gleixner:

 - Make objtool work for big-endian cross compiles

 - Make stack tracking via stack pointer memory operations match
   push/pop semantics to prepare for architectures w/o PUSH/POP
   instructions.

 - Add support for analyzing alternatives

 - Improve retpoline detection and handling

 - Improve assembly code coverage on x86

 - Provide support for inlined stack switching

* tag 'objtool-core-2021-02-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (33 commits)
  objtool: Support stack-swizzle
  objtool,x86: Additionally decode: mov %rsp, (%reg)
  x86/unwind/orc: Change REG_SP_INDIRECT
  x86/power: Support objtool validation in hibernate_asm_64.S
  x86/power: Move restore_registers() to top of the file
  x86/power: Annotate indirect branches as safe
  x86/acpi: Support objtool validation in wakeup_64.S
  x86/acpi: Annotate indirect branch as safe
  x86/ftrace: Support objtool vmlinux.o validation in ftrace_64.S
  x86/xen/pvh: Annotate indirect branch as safe
  x86/xen: Support objtool vmlinux.o validation in xen-head.S
  x86/xen: Support objtool validation in xen-asm.S
  objtool: Add xen_start_kernel() to noreturn list
  objtool: Combine UNWIND_HINT_RET_OFFSET and UNWIND_HINT_FUNC
  objtool: Add asm version of STACK_FRAME_NON_STANDARD
  objtool: Assume only ELF functions do sibling calls
  x86/ftrace: Add UNWIND_HINT_FUNC annotation for ftrace_stub
  objtool: Support retpoline jump detection for vmlinux.o
  objtool: Fix ".cold" section suffix check for newer versions of GCC
  objtool: Fix retpoline detection in asm code
  ...
  • Loading branch information
Linus Torvalds committed Feb 23, 2021
2 parents 79db4d2 + aafeb14 commit a56ff24
Show file tree
Hide file tree
Showing 49 changed files with 962 additions and 597 deletions.
45 changes: 45 additions & 0 deletions arch/x86/include/asm/insn.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@
* Copyright (C) IBM Corporation, 2009
*/

#include <asm/byteorder.h>
/* insn_attr_t is defined in inat.h */
#include <asm/inat.h>

#if defined(__BYTE_ORDER) ? __BYTE_ORDER == __LITTLE_ENDIAN : defined(__LITTLE_ENDIAN)

struct insn_field {
union {
insn_value_t value;
Expand All @@ -20,6 +23,48 @@ struct insn_field {
unsigned char nbytes;
};

static inline void insn_field_set(struct insn_field *p, insn_value_t v,
unsigned char n)
{
p->value = v;
p->nbytes = n;
}

static inline void insn_set_byte(struct insn_field *p, unsigned char n,
insn_byte_t v)
{
p->bytes[n] = v;
}

#else

struct insn_field {
insn_value_t value;
union {
insn_value_t little;
insn_byte_t bytes[4];
};
/* !0 if we've run insn_get_xxx() for this field */
unsigned char got;
unsigned char nbytes;
};

static inline void insn_field_set(struct insn_field *p, insn_value_t v,
unsigned char n)
{
p->value = v;
p->little = __cpu_to_le32(v);
p->nbytes = n;
}

static inline void insn_set_byte(struct insn_field *p, unsigned char n,
insn_byte_t v)
{
p->bytes[n] = v;
p->value = __le32_to_cpu(p->little);
}
#endif

struct insn {
struct insn_field prefixes; /*
* Prefixes
Expand Down
10 changes: 10 additions & 0 deletions arch/x86/include/asm/orc_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
#define ORC_REG_MAX 15

#ifndef __ASSEMBLY__
#include <asm/byteorder.h>

/*
* This struct is more or less a vastly simplified version of the DWARF Call
* Frame Information standard. It contains only the necessary parts of DWARF
Expand All @@ -51,10 +53,18 @@
struct orc_entry {
s16 sp_offset;
s16 bp_offset;
#if defined(__LITTLE_ENDIAN_BITFIELD)
unsigned sp_reg:4;
unsigned bp_reg:4;
unsigned type:2;
unsigned end:1;
#elif defined(__BIG_ENDIAN_BITFIELD)
unsigned bp_reg:4;
unsigned sp_reg:4;
unsigned unused:5;
unsigned end:1;
unsigned type:2;
#endif
} __packed;

#endif /* __ASSEMBLY__ */
Expand Down
13 changes: 2 additions & 11 deletions arch/x86/include/asm/unwind_hints.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,8 @@
UNWIND_HINT_REGS base=\base offset=\offset partial=1
.endm

.macro UNWIND_HINT_FUNC sp_offset=8
UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=\sp_offset type=UNWIND_HINT_TYPE_CALL
.endm

/*
* RET_OFFSET: Used on instructions that terminate a function; mostly RETURN
* and sibling calls. On these, sp_offset denotes the expected offset from
* initial_func_cfi.
*/
.macro UNWIND_HINT_RET_OFFSET sp_offset=8
UNWIND_HINT sp_reg=ORC_REG_SP type=UNWIND_HINT_TYPE_RET_OFFSET sp_offset=\sp_offset
.macro UNWIND_HINT_FUNC
UNWIND_HINT sp_reg=ORC_REG_SP sp_offset=8 type=UNWIND_HINT_TYPE_FUNC
.endm

#endif /* __ASSEMBLY__ */
Expand Down
1 change: 0 additions & 1 deletion arch/x86/kernel/acpi/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
OBJECT_FILES_NON_STANDARD_wakeup_$(BITS).o := y

obj-$(CONFIG_ACPI) += boot.o
obj-$(CONFIG_ACPI_SLEEP) += sleep.o wakeup_$(BITS).o
Expand Down
4 changes: 4 additions & 0 deletions arch/x86/kernel/acpi/wakeup_64.S
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-only */
.text
#include <linux/linkage.h>
#include <linux/objtool.h>
#include <asm/segment.h>
#include <asm/pgtable_types.h>
#include <asm/page_types.h>
#include <asm/msr.h>
#include <asm/asm-offsets.h>
#include <asm/frame.h>
#include <asm/nospec-branch.h>

# Copyright 2003 Pavel Machek <pavel@suse.cz

Expand Down Expand Up @@ -39,6 +41,7 @@ SYM_FUNC_START(wakeup_long64)
movq saved_rbp, %rbp

movq saved_rip, %rax
ANNOTATE_RETPOLINE_SAFE
jmp *%rax
SYM_FUNC_END(wakeup_long64)

Expand Down Expand Up @@ -126,6 +129,7 @@ SYM_FUNC_START(do_suspend_lowlevel)
FRAME_END
jmp restore_processor_state
SYM_FUNC_END(do_suspend_lowlevel)
STACK_FRAME_NON_STANDARD do_suspend_lowlevel

.data
saved_rbp: .quad 0
Expand Down
8 changes: 4 additions & 4 deletions arch/x86/kernel/ftrace_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ SYM_INNER_LABEL(ftrace_graph_call, SYM_L_GLOBAL)
* It is also used to copy the retq for trampolines.
*/
SYM_INNER_LABEL_ALIGN(ftrace_stub, SYM_L_WEAK)
UNWIND_HINT_FUNC
retq
SYM_FUNC_END(ftrace_epilogue)

Expand Down Expand Up @@ -276,7 +277,7 @@ SYM_INNER_LABEL(ftrace_regs_caller_end, SYM_L_GLOBAL)
restore_mcount_regs 8
/* Restore flags */
popfq
UNWIND_HINT_RET_OFFSET
UNWIND_HINT_FUNC
jmp ftrace_epilogue

SYM_FUNC_END(ftrace_regs_caller)
Expand Down Expand Up @@ -333,8 +334,7 @@ SYM_FUNC_START(ftrace_graph_caller)
retq
SYM_FUNC_END(ftrace_graph_caller)

SYM_CODE_START(return_to_handler)
UNWIND_HINT_EMPTY
SYM_FUNC_START(return_to_handler)
subq $24, %rsp

/* Save the return values */
Expand All @@ -349,5 +349,5 @@ SYM_CODE_START(return_to_handler)
movq (%rsp), %rax
addq $24, %rsp
JMP_NOSPEC rdi
SYM_CODE_END(return_to_handler)
SYM_FUNC_END(return_to_handler)
#endif
5 changes: 4 additions & 1 deletion arch/x86/kernel/unwind_orc.c
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ bool unwind_next_frame(struct unwind_state *state)
break;

case ORC_REG_SP_INDIRECT:
sp = state->sp + orc->sp_offset;
sp = state->sp;
indirect = true;
break;

Expand Down Expand Up @@ -521,6 +521,9 @@ bool unwind_next_frame(struct unwind_state *state)
if (indirect) {
if (!deref_stack_reg(state, sp, &sp))
goto err;

if (orc->sp_reg == ORC_REG_SP_INDIRECT)
sp += orc->sp_offset;
}

/* Find IP, SP and possibly regs: */
Expand Down
Loading

0 comments on commit a56ff24

Please sign in to comment.