linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [GIT PULL] objtool fixes
@ 2020-04-25  9:04 Ingo Molnar
  2020-04-25 19:30 ` pr-tracker-bot
  0 siblings, 1 reply; 16+ messages in thread
From: Ingo Molnar @ 2020-04-25  9:04 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-kernel, Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner,
	Borislav Petkov, Andrew Morton

Linus,

Please pull the latest objtool/urgent git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git objtool-urgent-2020-04-25

   # HEAD: 7f9b34f36cf6b2099f19e679a9e8315c955ef2ee objtool: Fix off-by-one in symbol_by_offset()

Two fixes: fix an off-by-one bug, and fix 32-bit builds on 64-bit systems.

 Thanks,

	Ingo

------------------>
Julien Thierry (1):
      objtool: Fix off-by-one in symbol_by_offset()

Peter Zijlstra (1):
      objtool: Fix 32bit cross builds


 tools/objtool/elf.c | 2 +-
 tools/objtool/elf.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 09ddc8f1def3..c4857fa3f1d1 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -105,7 +105,7 @@ static int symbol_by_offset(const void *key, const struct rb_node *node)
 
 	if (*o < s->offset)
 		return -1;
-	if (*o > s->offset + s->len)
+	if (*o >= s->offset + s->len)
 		return 1;
 
 	return 0;
diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
index ebbb10c61e24..0b79c2353a21 100644
--- a/tools/objtool/elf.h
+++ b/tools/objtool/elf.h
@@ -99,7 +99,7 @@ static inline u32 sec_offset_hash(struct section *sec, unsigned long offset)
 	offset &= OFFSET_STRIDE_MASK;
 
 	ol = offset;
-	oh = offset >> 32;
+	oh = (offset >> 16) >> 16;
 
 	__jhash_mix(ol, oh, idx);
 

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [GIT PULL] objtool fixes
  2020-04-25  9:04 [GIT PULL] objtool fixes Ingo Molnar
@ 2020-04-25 19:30 ` pr-tracker-bot
  0 siblings, 0 replies; 16+ messages in thread
From: pr-tracker-bot @ 2020-04-25 19:30 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Linus Torvalds, linux-kernel, Josh Poimboeuf, Peter Zijlstra,
	Thomas Gleixner, Borislav Petkov, Andrew Morton

The pull request you sent on Sat, 25 Apr 2020 11:04:40 +0200:

> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git objtool-urgent-2020-04-25

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/9b3e59e3deccef70afece5e6484a324cbc126bcd

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.wiki.kernel.org/userdoc/prtracker

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [GIT PULL] objtool fixes
  2021-06-24  6:54 Ingo Molnar
@ 2021-06-24 16:34 ` pr-tracker-bot
  0 siblings, 0 replies; 16+ messages in thread
From: pr-tracker-bot @ 2021-06-24 16:34 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Linus Torvalds, linux-kernel, Peter Zijlstra, Josh Poimboeuf,
	Thomas Gleixner, Borislav Petkov, Andrew Morton

The pull request you sent on Thu, 24 Jun 2021 08:54:41 +0200:

> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git objtool-urgent-2021-06-24

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/c0e457851fffd90eac14ad2528dfea3994945c28

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [GIT PULL] objtool fixes
@ 2021-06-24  6:54 Ingo Molnar
  2021-06-24 16:34 ` pr-tracker-bot
  0 siblings, 1 reply; 16+ messages in thread
From: Ingo Molnar @ 2021-06-24  6:54 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-kernel, Peter Zijlstra, Josh Poimboeuf, Thomas Gleixner,
	Borislav Petkov, Andrew Morton

Linus,

Please pull the latest objtool/urgent git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git objtool-urgent-2021-06-24

   # HEAD: 49faa77759b211fff344898edc23bb780707fff5 locking/lockdep: Improve noinstr vs errors

Address a number of objtool warnings that got reported.

No change in behavior intended, but code generation might be
impacted by:

   1f008d46f124: ("x86: Always inline task_size_max()")

 Thanks,

	Ingo

------------------>
Peter Zijlstra (6):
      objtool/x86: Ignore __x86_indirect_alt_* symbols
      x86/entry: Fix noinstr fail in __do_fast_syscall_32()
      x86/xen: Fix noinstr fail in xen_pv_evtchn_do_upcall()
      x86/xen: Fix noinstr fail in exc_xen_unknown_trap()
      x86: Always inline task_size_max()
      locking/lockdep: Improve noinstr vs errors


 arch/x86/entry/common.c        | 5 +++--
 arch/x86/include/asm/page_64.h | 2 +-
 arch/x86/lib/retpoline.S       | 4 ++++
 arch/x86/xen/enlighten_pv.c    | 2 ++
 include/linux/debug_locks.h    | 2 ++
 kernel/locking/lockdep.c       | 4 +++-
 lib/debug_locks.c              | 2 +-
 7 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/arch/x86/entry/common.c b/arch/x86/entry/common.c
index 7b2542b13ebd..04bce95bc7e3 100644
--- a/arch/x86/entry/common.c
+++ b/arch/x86/entry/common.c
@@ -130,8 +130,8 @@ static noinstr bool __do_fast_syscall_32(struct pt_regs *regs)
 		/* User code screwed up. */
 		regs->ax = -EFAULT;
 
-		instrumentation_end();
 		local_irq_disable();
+		instrumentation_end();
 		irqentry_exit_to_user_mode(regs);
 		return false;
 	}
@@ -269,15 +269,16 @@ __visible noinstr void xen_pv_evtchn_do_upcall(struct pt_regs *regs)
 	irqentry_state_t state = irqentry_enter(regs);
 	bool inhcall;
 
+	instrumentation_begin();
 	run_sysvec_on_irqstack_cond(__xen_pv_evtchn_do_upcall, regs);
 
 	inhcall = get_and_clear_inhcall();
 	if (inhcall && !WARN_ON_ONCE(state.exit_rcu)) {
-		instrumentation_begin();
 		irqentry_exit_cond_resched();
 		instrumentation_end();
 		restore_inhcall(inhcall);
 	} else {
+		instrumentation_end();
 		irqentry_exit(regs, state);
 	}
 }
diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h
index ca840fec7776..4bde0dc66100 100644
--- a/arch/x86/include/asm/page_64.h
+++ b/arch/x86/include/asm/page_64.h
@@ -75,7 +75,7 @@ void copy_page(void *to, void *from);
  *
  * With page table isolation enabled, we map the LDT in ... [stay tuned]
  */
-static inline unsigned long task_size_max(void)
+static __always_inline unsigned long task_size_max(void)
 {
 	unsigned long ret;
 
diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S
index 4d32cb06ffd5..ec9922cba30a 100644
--- a/arch/x86/lib/retpoline.S
+++ b/arch/x86/lib/retpoline.S
@@ -58,12 +58,16 @@ SYM_FUNC_START_NOALIGN(__x86_indirect_alt_call_\reg)
 2:	.skip	5-(2b-1b), 0x90
 SYM_FUNC_END(__x86_indirect_alt_call_\reg)
 
+STACK_FRAME_NON_STANDARD(__x86_indirect_alt_call_\reg)
+
 SYM_FUNC_START_NOALIGN(__x86_indirect_alt_jmp_\reg)
 	ANNOTATE_RETPOLINE_SAFE
 1:	jmp	*%\reg
 2:	.skip	5-(2b-1b), 0x90
 SYM_FUNC_END(__x86_indirect_alt_jmp_\reg)
 
+STACK_FRAME_NON_STANDARD(__x86_indirect_alt_jmp_\reg)
+
 .endm
 
 /*
diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index e87699aa2dc8..03149422dce2 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -592,8 +592,10 @@ DEFINE_IDTENTRY_RAW(xenpv_exc_debug)
 DEFINE_IDTENTRY_RAW(exc_xen_unknown_trap)
 {
 	/* This should never happen and there is no way to handle it. */
+	instrumentation_begin();
 	pr_err("Unknown trap in Xen PV mode.");
 	BUG();
+	instrumentation_end();
 }
 
 #ifdef CONFIG_X86_MCE
diff --git a/include/linux/debug_locks.h b/include/linux/debug_locks.h
index 2915f56ad421..edb5c186b0b7 100644
--- a/include/linux/debug_locks.h
+++ b/include/linux/debug_locks.h
@@ -27,8 +27,10 @@ extern int debug_locks_off(void);
 	int __ret = 0;							\
 									\
 	if (!oops_in_progress && unlikely(c)) {				\
+		instrumentation_begin();				\
 		if (debug_locks_off() && !debug_locks_silent)		\
 			WARN(1, "DEBUG_LOCKS_WARN_ON(%s)", #c);		\
+		instrumentation_end();					\
 		__ret = 1;						\
 	}								\
 	__ret;								\
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index 7641bd407239..e32313072506 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -843,7 +843,7 @@ static int count_matching_names(struct lock_class *new_class)
 }
 
 /* used from NMI context -- must be lockless */
-static __always_inline struct lock_class *
+static noinstr struct lock_class *
 look_up_lock_class(const struct lockdep_map *lock, unsigned int subclass)
 {
 	struct lockdep_subclass_key *key;
@@ -851,12 +851,14 @@ look_up_lock_class(const struct lockdep_map *lock, unsigned int subclass)
 	struct lock_class *class;
 
 	if (unlikely(subclass >= MAX_LOCKDEP_SUBCLASSES)) {
+		instrumentation_begin();
 		debug_locks_off();
 		printk(KERN_ERR
 			"BUG: looking up invalid subclass: %u\n", subclass);
 		printk(KERN_ERR
 			"turning off the locking correctness validator.\n");
 		dump_stack();
+		instrumentation_end();
 		return NULL;
 	}
 
diff --git a/lib/debug_locks.c b/lib/debug_locks.c
index 06d3135bd184..a75ee30b77cb 100644
--- a/lib/debug_locks.c
+++ b/lib/debug_locks.c
@@ -36,7 +36,7 @@ EXPORT_SYMBOL_GPL(debug_locks_silent);
 /*
  * Generic 'turn off all lock debugging' function:
  */
-noinstr int debug_locks_off(void)
+int debug_locks_off(void)
 {
 	if (debug_locks && __debug_locks_off()) {
 		if (!debug_locks_silent) {

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [GIT PULL] objtool fixes
  2021-06-12 12:37 Ingo Molnar
@ 2021-06-12 19:09 ` pr-tracker-bot
  0 siblings, 0 replies; 16+ messages in thread
From: pr-tracker-bot @ 2021-06-12 19:09 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Linus Torvalds, linux-kernel, Peter Zijlstra, Thomas Gleixner,
	Borislav Petkov, Andrew Morton, Josh Poimboeuf

The pull request you sent on Sat, 12 Jun 2021 14:37:46 +0200:

> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git objtool-urgent-2021-06-12

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/768895fb774d7af32d17cf3a455b0bd6df272f14

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [GIT PULL] objtool fixes
@ 2021-06-12 12:37 Ingo Molnar
  2021-06-12 19:09 ` pr-tracker-bot
  0 siblings, 1 reply; 16+ messages in thread
From: Ingo Molnar @ 2021-06-12 12:37 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-kernel, Peter Zijlstra, Thomas Gleixner, Borislav Petkov,
	Andrew Morton, Josh Poimboeuf

Linus,

Please pull the latest objtool/urgent git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git objtool-urgent-2021-06-12

   # HEAD: 2d49b721dc18c113d5221f4cf5a6104eb66cb7f2 objtool: Only rewrite unconditional retpoline thunk calls

Two objtool fixes:

 - fix a bug that corrupts the code by mistakenly rewriting
   conditional jumps,
 - and fix another bug generating an incorrect ELF symbol table
   during retpoline rewriting.

 Thanks,

	Ingo

------------------>
Peter Zijlstra (2):
      objtool: Fix .symtab_shndx handling for elf_create_undef_symbol()
      objtool: Only rewrite unconditional retpoline thunk calls


 tools/objtool/arch/x86/decode.c |  4 ++++
 tools/objtool/elf.c             | 25 ++++++++++++++++++++++++-
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 24295d39713b..523aa4157f80 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -747,6 +747,10 @@ int arch_rewrite_retpolines(struct objtool_file *file)
 
 	list_for_each_entry(insn, &file->retpoline_call_list, call_node) {
 
+		if (insn->type != INSN_JUMP_DYNAMIC &&
+		    insn->type != INSN_CALL_DYNAMIC)
+			continue;
+
 		if (!strcmp(insn->sec->name, ".text.__x86.indirect_thunk"))
 			continue;
 
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 743c2e9d0f56..41bca1d13d8e 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -717,7 +717,7 @@ static int elf_add_string(struct elf *elf, struct section *strtab, char *str)
 
 struct symbol *elf_create_undef_symbol(struct elf *elf, const char *name)
 {
-	struct section *symtab;
+	struct section *symtab, *symtab_shndx;
 	struct symbol *sym;
 	Elf_Data *data;
 	Elf_Scn *s;
@@ -769,6 +769,29 @@ struct symbol *elf_create_undef_symbol(struct elf *elf, const char *name)
 	symtab->len += data->d_size;
 	symtab->changed = true;
 
+	symtab_shndx = find_section_by_name(elf, ".symtab_shndx");
+	if (symtab_shndx) {
+		s = elf_getscn(elf->elf, symtab_shndx->idx);
+		if (!s) {
+			WARN_ELF("elf_getscn");
+			return NULL;
+		}
+
+		data = elf_newdata(s);
+		if (!data) {
+			WARN_ELF("elf_newdata");
+			return NULL;
+		}
+
+		data->d_buf = &sym->sym.st_size; /* conveniently 0 */
+		data->d_size = sizeof(Elf32_Word);
+		data->d_align = 4;
+		data->d_type = ELF_T_WORD;
+
+		symtab_shndx->len += 4;
+		symtab_shndx->changed = true;
+	}
+
 	sym->sec = find_section_by_index(elf, 0);
 
 	elf_add_symbol(elf, sym);

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [GIT PULL] objtool fixes
  2021-05-15  7:46 Ingo Molnar
@ 2021-05-15 17:55 ` pr-tracker-bot
  0 siblings, 0 replies; 16+ messages in thread
From: pr-tracker-bot @ 2021-05-15 17:55 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Linus Torvalds, linux-kernel, Josh Poimboeuf, Peter Zijlstra,
	Thomas Gleixner, Borislav Petkov, Andrew Morton

The pull request you sent on Sat, 15 May 2021 09:46:45 +0200:

> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git objtool-urgent-2021-05-15

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/e7c425b7441a96b95a75304aed369077f71e3e83

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/prtracker.html

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [GIT PULL] objtool fixes
@ 2021-05-15  7:46 Ingo Molnar
  2021-05-15 17:55 ` pr-tracker-bot
  0 siblings, 1 reply; 16+ messages in thread
From: Ingo Molnar @ 2021-05-15  7:46 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-kernel, Josh Poimboeuf, Peter Zijlstra, Thomas Gleixner,
	Borislav Petkov, Andrew Morton

Linus,

Please pull the latest objtool/urgent git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git objtool-urgent-2021-05-15

   # HEAD: f66c05d6baf36069c01a02f869bebb75586f2318 objtool/x86: Fix elf_add_alternative() endianness

Fix a couple of endianness bugs that crept in.

 Thanks,

	Ingo

------------------>
Vasily Gorbik (2):
      objtool: Fix elf_create_undef_symbol() endianness
      objtool/x86: Fix elf_add_alternative() endianness


 tools/objtool/arch/x86/decode.c | 3 ++-
 tools/objtool/elf.c             | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index cedf3ede7545..24295d39713b 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -19,6 +19,7 @@
 #include <objtool/elf.h>
 #include <objtool/arch.h>
 #include <objtool/warn.h>
+#include <objtool/endianness.h>
 #include <arch/elf.h>
 
 static int is_x86_64(const struct elf *elf)
@@ -725,7 +726,7 @@ static int elf_add_alternative(struct elf *elf,
 		return -1;
 	}
 
-	alt->cpuid = cpuid;
+	alt->cpuid = bswap_if_needed(cpuid);
 	alt->instrlen = orig_len;
 	alt->replacementlen = repl_len;
 
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index d08f5f3670f8..743c2e9d0f56 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -762,6 +762,7 @@ struct symbol *elf_create_undef_symbol(struct elf *elf, const char *name)
 	data->d_buf = &sym->sym;
 	data->d_size = sizeof(sym->sym);
 	data->d_align = 1;
+	data->d_type = ELF_T_SYM;
 
 	sym->idx = symtab->len / sizeof(sym->sym);
 

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [GIT PULL] objtool fixes
  2018-11-30  6:18 Ingo Molnar
@ 2018-11-30 21:00 ` pr-tracker-bot
  0 siblings, 0 replies; 16+ messages in thread
From: pr-tracker-bot @ 2018-11-30 21:00 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Linus Torvalds, linux-kernel, Josh Poimboeuf, Thomas Gleixner,
	Peter Zijlstra, Borislav Petkov, Andrew Morton

The pull request you sent on Fri, 30 Nov 2018 07:18:53 +0100:

> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-urgent-for-linus

has been merged into torvalds/linux.git:
https://git.kernel.org/torvalds/c/575d7d0d6f5c6feb896fae2e70578a1ab6d474b5

Thank you!

-- 
Deet-doot-dot, I am a bot.
https://korg.wiki.kernel.org/userdoc/prtracker

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [GIT PULL] objtool fixes
@ 2018-11-30  6:18 Ingo Molnar
  2018-11-30 21:00 ` pr-tracker-bot
  0 siblings, 1 reply; 16+ messages in thread
From: Ingo Molnar @ 2018-11-30  6:18 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-kernel, Josh Poimboeuf, Thomas Gleixner, Peter Zijlstra,
	Borislav Petkov, Andrew Morton

Linus,

Please pull the latest core-urgent-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-urgent-for-linus

   # HEAD: 22566c1603030f0a036ad564634b064ad1a55db2 objtool: Fix segfault in .cold detection with -ffunction-sections

Two fixes for boundary conditions.

 Thanks,

	Ingo

------------------>
Artem Savkov (2):
      objtool: Fix double-free in .cold detection error path
      objtool: Fix segfault in .cold detection with -ffunction-sections


 tools/objtool/elf.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index 6dbb9fae0f9d..b8f3cca8e58b 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -31,6 +31,8 @@
 #include "elf.h"
 #include "warn.h"
 
+#define MAX_NAME_LEN 128
+
 struct section *find_section_by_name(struct elf *elf, const char *name)
 {
 	struct section *sec;
@@ -298,6 +300,8 @@ static int read_symbols(struct elf *elf)
 	/* Create parent/child links for any cold subfunctions */
 	list_for_each_entry(sec, &elf->sections, list) {
 		list_for_each_entry(sym, &sec->symbol_list, list) {
+			char pname[MAX_NAME_LEN + 1];
+			size_t pnamelen;
 			if (sym->type != STT_FUNC)
 				continue;
 			sym->pfunc = sym->cfunc = sym;
@@ -305,14 +309,21 @@ static int read_symbols(struct elf *elf)
 			if (!coldstr)
 				continue;
 
-			coldstr[0] = '\0';
-			pfunc = find_symbol_by_name(elf, sym->name);
-			coldstr[0] = '.';
+			pnamelen = coldstr - sym->name;
+			if (pnamelen > MAX_NAME_LEN) {
+				WARN("%s(): parent function name exceeds maximum length of %d characters",
+				     sym->name, MAX_NAME_LEN);
+				return -1;
+			}
+
+			strncpy(pname, sym->name, pnamelen);
+			pname[pnamelen] = '\0';
+			pfunc = find_symbol_by_name(elf, pname);
 
 			if (!pfunc) {
 				WARN("%s(): can't find parent function",
 				     sym->name);
-				goto err;
+				return -1;
 			}
 
 			sym->pfunc = pfunc;

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [GIT PULL] objtool fixes
@ 2017-11-26 12:34 Ingo Molnar
  0 siblings, 0 replies; 16+ messages in thread
From: Ingo Molnar @ 2017-11-26 12:34 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-kernel, Josh Poimboeuf, Thomas Gleixner, Peter Zijlstra,
	Andrew Morton

Linus,

Please pull the latest core-urgent-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-urgent-for-linus

   # HEAD: a356d2ae50790f49858ebed35da9e206336fafee tools/headers: Sync objtool UAPI header

A handful of objtool fixes, most of them related to making the UAPI header-syncing 
warnings easier to read and easier to act upon.

 Thanks,

	Ingo

------------------>
Ingo Molnar (1):
      tools/headers: Sync objtool UAPI header

Josh Poimboeuf (5):
      objtool: Add a comment for the unreachable annotation macros
      objtool: Make unreachable annotation inline asms explicitly volatile
      objtool: Move synced files to their original relative locations
      objtool: Move kernel headers/code sync check to a script
      objtool: Fix cross-build


 include/linux/compiler.h                           | 21 ++++++++++------
 tools/objtool/.gitignore                           |  2 +-
 tools/objtool/Makefile                             | 22 ++++------------
 tools/objtool/arch/x86/Build                       | 10 ++++----
 tools/objtool/arch/x86/decode.c                    |  6 ++---
 .../objtool/arch/x86/{insn => include/asm}/inat.h  | 12 ++++++++-
 .../arch/x86/{insn => include/asm}/inat_types.h    |  0
 .../objtool/arch/x86/{insn => include/asm}/insn.h  |  2 +-
 .../objtool/{ => arch/x86/include/asm}/orc_types.h |  0
 tools/objtool/arch/x86/{insn => lib}/inat.c        |  2 +-
 tools/objtool/arch/x86/{insn => lib}/insn.c        |  4 +--
 .../arch/x86/{insn => lib}/x86-opcode-map.txt      |  0
 .../arch/x86/{insn => tools}/gen-insn-attr-x86.awk |  0
 tools/objtool/orc.h                                |  2 +-
 tools/objtool/sync-check.sh                        | 29 ++++++++++++++++++++++
 15 files changed, 72 insertions(+), 40 deletions(-)
 rename tools/objtool/arch/x86/{insn => include/asm}/inat.h (95%)
 rename tools/objtool/arch/x86/{insn => include/asm}/inat_types.h (100%)
 rename tools/objtool/arch/x86/{insn => include/asm}/insn.h (99%)
 rename tools/objtool/{ => arch/x86/include/asm}/orc_types.h (100%)
 rename tools/objtool/arch/x86/{insn => lib}/inat.c (99%)
 rename tools/objtool/arch/x86/{insn => lib}/insn.c (99%)
 rename tools/objtool/arch/x86/{insn => lib}/x86-opcode-map.txt (100%)
 rename tools/objtool/arch/x86/{insn => tools}/gen-insn-attr-x86.awk (100%)
 create mode 100755 tools/objtool/sync-check.sh

diff --git a/include/linux/compiler.h b/include/linux/compiler.h
index 3672353a0acd..188ed9f65517 100644
--- a/include/linux/compiler.h
+++ b/include/linux/compiler.h
@@ -88,17 +88,22 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val,
 
 /* Unreachable code */
 #ifdef CONFIG_STACK_VALIDATION
+/*
+ * These macros help objtool understand GCC code flow for unreachable code.
+ * The __COUNTER__ based labels are a hack to make each instance of the macros
+ * unique, to convince GCC not to merge duplicate inline asm statements.
+ */
 #define annotate_reachable() ({						\
-	asm("%c0:\n\t"							\
-	    ".pushsection .discard.reachable\n\t"			\
-	    ".long %c0b - .\n\t"					\
-	    ".popsection\n\t" : : "i" (__COUNTER__));			\
+	asm volatile("%c0:\n\t"						\
+		     ".pushsection .discard.reachable\n\t"		\
+		     ".long %c0b - .\n\t"				\
+		     ".popsection\n\t" : : "i" (__COUNTER__));		\
 })
 #define annotate_unreachable() ({					\
-	asm("%c0:\n\t"							\
-	    ".pushsection .discard.unreachable\n\t"			\
-	    ".long %c0b - .\n\t"					\
-	    ".popsection\n\t" : : "i" (__COUNTER__));			\
+	asm volatile("%c0:\n\t"						\
+		     ".pushsection .discard.unreachable\n\t"		\
+		     ".long %c0b - .\n\t"				\
+		     ".popsection\n\t" : : "i" (__COUNTER__));		\
 })
 #define ASM_UNREACHABLE							\
 	"999:\n\t"							\
diff --git a/tools/objtool/.gitignore b/tools/objtool/.gitignore
index d3102c865a95..914cff12899b 100644
--- a/tools/objtool/.gitignore
+++ b/tools/objtool/.gitignore
@@ -1,3 +1,3 @@
-arch/x86/insn/inat-tables.c
+arch/x86/lib/inat-tables.c
 objtool
 fixdep
diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
index 424b1965d06f..0f94af3ccaaa 100644
--- a/tools/objtool/Makefile
+++ b/tools/objtool/Makefile
@@ -25,7 +25,9 @@ OBJTOOL_IN := $(OBJTOOL)-in.o
 
 all: $(OBJTOOL)
 
-INCLUDES := -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi
+INCLUDES := -I$(srctree)/tools/include \
+	    -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \
+	    -I$(srctree)/tools/objtool/arch/$(ARCH)/include
 WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed
 CFLAGS   += -Wall -Werror $(WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES)
 LDFLAGS  += -lelf $(LIBSUBCMD)
@@ -41,22 +43,8 @@ include $(srctree)/tools/build/Makefile.include
 $(OBJTOOL_IN): fixdep FORCE
 	@$(MAKE) $(build)=objtool
 
-# Busybox's diff doesn't have -I, avoid warning in that case
-#
 $(OBJTOOL): $(LIBSUBCMD) $(OBJTOOL_IN)
-	@(diff -I 2>&1 | grep -q 'option requires an argument' && \
-	test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \
-	diff -I'^#include' arch/x86/insn/insn.c ../../arch/x86/lib/insn.c >/dev/null && \
-	diff -I'^#include' arch/x86/insn/inat.c ../../arch/x86/lib/inat.c >/dev/null && \
-	diff arch/x86/insn/x86-opcode-map.txt ../../arch/x86/lib/x86-opcode-map.txt >/dev/null && \
-	diff arch/x86/insn/gen-insn-attr-x86.awk ../../arch/x86/tools/gen-insn-attr-x86.awk >/dev/null && \
-	diff -I'^#include' arch/x86/insn/insn.h ../../arch/x86/include/asm/insn.h >/dev/null && \
-	diff -I'^#include' arch/x86/insn/inat.h ../../arch/x86/include/asm/inat.h >/dev/null && \
-	diff -I'^#include' arch/x86/insn/inat_types.h ../../arch/x86/include/asm/inat_types.h >/dev/null) \
-	|| echo "warning: objtool: x86 instruction decoder differs from kernel" >&2 )) || true
-	@(test -d ../../kernel -a -d ../../tools -a -d ../objtool && (( \
-	diff ../../arch/x86/include/asm/orc_types.h orc_types.h >/dev/null) \
-	|| echo "warning: objtool: orc_types.h differs from kernel" >&2 )) || true
+	@./sync-check.sh
 	$(QUIET_LINK)$(CC) $(OBJTOOL_IN) $(LDFLAGS) -o $@
 
 
@@ -66,7 +54,7 @@ $(LIBSUBCMD): fixdep FORCE
 clean:
 	$(call QUIET_CLEAN, objtool) $(RM) $(OBJTOOL)
 	$(Q)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
-	$(Q)$(RM) $(OUTPUT)arch/x86/insn/inat-tables.c $(OUTPUT)fixdep
+	$(Q)$(RM) $(OUTPUT)arch/x86/lib/inat-tables.c $(OUTPUT)fixdep
 
 FORCE:
 
diff --git a/tools/objtool/arch/x86/Build b/tools/objtool/arch/x86/Build
index debbdb0b5c43..b998412c017d 100644
--- a/tools/objtool/arch/x86/Build
+++ b/tools/objtool/arch/x86/Build
@@ -1,12 +1,12 @@
 objtool-y += decode.o
 
-inat_tables_script = arch/x86/insn/gen-insn-attr-x86.awk
-inat_tables_maps = arch/x86/insn/x86-opcode-map.txt
+inat_tables_script = arch/x86/tools/gen-insn-attr-x86.awk
+inat_tables_maps = arch/x86/lib/x86-opcode-map.txt
 
-$(OUTPUT)arch/x86/insn/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
+$(OUTPUT)arch/x86/lib/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
 	$(call rule_mkdir)
 	$(Q)$(call echo-cmd,gen)$(AWK) -f $(inat_tables_script) $(inat_tables_maps) > $@
 
-$(OUTPUT)arch/x86/decode.o: $(OUTPUT)arch/x86/insn/inat-tables.c
+$(OUTPUT)arch/x86/decode.o: $(OUTPUT)arch/x86/lib/inat-tables.c
 
-CFLAGS_decode.o += -I$(OUTPUT)arch/x86/insn
+CFLAGS_decode.o += -I$(OUTPUT)arch/x86/lib
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 34a579f806e3..8acfc47af70e 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -19,9 +19,9 @@
 #include <stdlib.h>
 
 #define unlikely(cond) (cond)
-#include "insn/insn.h"
-#include "insn/inat.c"
-#include "insn/insn.c"
+#include <asm/insn.h>
+#include "lib/inat.c"
+#include "lib/insn.c"
 
 #include "../../elf.h"
 #include "../../arch.h"
diff --git a/tools/objtool/arch/x86/insn/inat.h b/tools/objtool/arch/x86/include/asm/inat.h
similarity index 95%
rename from tools/objtool/arch/x86/insn/inat.h
rename to tools/objtool/arch/x86/include/asm/inat.h
index 125ecd2a300d..1c78580e58be 100644
--- a/tools/objtool/arch/x86/insn/inat.h
+++ b/tools/objtool/arch/x86/include/asm/inat.h
@@ -20,7 +20,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
  */
-#include "inat_types.h"
+#include <asm/inat_types.h>
 
 /*
  * Internal bits. Don't use bitmasks directly, because these bits are
@@ -97,6 +97,16 @@
 #define INAT_MAKE_GROUP(grp)	((grp << INAT_GRP_OFFS) | INAT_MODRM)
 #define INAT_MAKE_IMM(imm)	(imm << INAT_IMM_OFFS)
 
+/* Identifiers for segment registers */
+#define INAT_SEG_REG_IGNORE	0
+#define INAT_SEG_REG_DEFAULT	1
+#define INAT_SEG_REG_CS		2
+#define INAT_SEG_REG_SS		3
+#define INAT_SEG_REG_DS		4
+#define INAT_SEG_REG_ES		5
+#define INAT_SEG_REG_FS		6
+#define INAT_SEG_REG_GS		7
+
 /* Attribute search APIs */
 extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
 extern int inat_get_last_prefix_id(insn_byte_t last_pfx);
diff --git a/tools/objtool/arch/x86/insn/inat_types.h b/tools/objtool/arch/x86/include/asm/inat_types.h
similarity index 100%
rename from tools/objtool/arch/x86/insn/inat_types.h
rename to tools/objtool/arch/x86/include/asm/inat_types.h
diff --git a/tools/objtool/arch/x86/insn/insn.h b/tools/objtool/arch/x86/include/asm/insn.h
similarity index 99%
rename from tools/objtool/arch/x86/insn/insn.h
rename to tools/objtool/arch/x86/include/asm/insn.h
index e23578c7b1be..b3e32b010ab1 100644
--- a/tools/objtool/arch/x86/insn/insn.h
+++ b/tools/objtool/arch/x86/include/asm/insn.h
@@ -21,7 +21,7 @@
  */
 
 /* insn_attr_t is defined in inat.h */
-#include "inat.h"
+#include <asm/inat.h>
 
 struct insn_field {
 	union {
diff --git a/tools/objtool/orc_types.h b/tools/objtool/arch/x86/include/asm/orc_types.h
similarity index 100%
rename from tools/objtool/orc_types.h
rename to tools/objtool/arch/x86/include/asm/orc_types.h
diff --git a/tools/objtool/arch/x86/insn/inat.c b/tools/objtool/arch/x86/lib/inat.c
similarity index 99%
rename from tools/objtool/arch/x86/insn/inat.c
rename to tools/objtool/arch/x86/lib/inat.c
index e4bf28e6f4c7..c1f01a8e9f65 100644
--- a/tools/objtool/arch/x86/insn/inat.c
+++ b/tools/objtool/arch/x86/lib/inat.c
@@ -18,7 +18,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
  */
-#include "insn.h"
+#include <asm/insn.h>
 
 /* Attribute tables are generated from opcode map */
 #include "inat-tables.c"
diff --git a/tools/objtool/arch/x86/insn/insn.c b/tools/objtool/arch/x86/lib/insn.c
similarity index 99%
rename from tools/objtool/arch/x86/insn/insn.c
rename to tools/objtool/arch/x86/lib/insn.c
index ca983e2bea8b..1088eb8f3a5f 100644
--- a/tools/objtool/arch/x86/insn/insn.c
+++ b/tools/objtool/arch/x86/lib/insn.c
@@ -23,8 +23,8 @@
 #else
 #include <string.h>
 #endif
-#include "inat.h"
-#include "insn.h"
+#include <asm/inat.h>
+#include <asm/insn.h>
 
 /* Verify next sizeof(t) bytes can be on the same instruction */
 #define validate_next(t, insn, n)	\
diff --git a/tools/objtool/arch/x86/insn/x86-opcode-map.txt b/tools/objtool/arch/x86/lib/x86-opcode-map.txt
similarity index 100%
rename from tools/objtool/arch/x86/insn/x86-opcode-map.txt
rename to tools/objtool/arch/x86/lib/x86-opcode-map.txt
diff --git a/tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk b/tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk
similarity index 100%
rename from tools/objtool/arch/x86/insn/gen-insn-attr-x86.awk
rename to tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk
diff --git a/tools/objtool/orc.h b/tools/objtool/orc.h
index a4139e386ef3..b0e92a6d0903 100644
--- a/tools/objtool/orc.h
+++ b/tools/objtool/orc.h
@@ -18,7 +18,7 @@
 #ifndef _ORC_H
 #define _ORC_H
 
-#include "orc_types.h"
+#include <asm/orc_types.h>
 
 struct objtool_file;
 
diff --git a/tools/objtool/sync-check.sh b/tools/objtool/sync-check.sh
new file mode 100755
index 000000000000..1470e74e9d66
--- /dev/null
+++ b/tools/objtool/sync-check.sh
@@ -0,0 +1,29 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+FILES='
+arch/x86/lib/insn.c
+arch/x86/lib/inat.c
+arch/x86/lib/x86-opcode-map.txt
+arch/x86/tools/gen-insn-attr-x86.awk
+arch/x86/include/asm/insn.h
+arch/x86/include/asm/inat.h
+arch/x86/include/asm/inat_types.h
+arch/x86/include/asm/orc_types.h
+'
+
+check()
+{
+	local file=$1
+
+	diff $file ../../$file > /dev/null ||
+		echo "Warning: synced file at 'tools/objtool/$file' differs from latest kernel version at '$file'"
+}
+
+if [ ! -d ../../kernel ] || [ ! -d ../../tools ] || [ ! -d ../objtool ]; then
+	exit 0
+fi
+
+for i in $FILES; do
+  check $i
+done

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [GIT PULL] objtool fixes
@ 2017-03-01 22:01 Ingo Molnar
  0 siblings, 0 replies; 16+ messages in thread
From: Ingo Molnar @ 2017-03-01 22:01 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-kernel, Josh Poimboeuf, Thomas Gleixner, Peter Zijlstra,
	Andrew Morton

Linus,

Please pull the latest core-urgent-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-urgent-for-linus

   # HEAD: e390f9a9689a42f477a6073e2e7df530a4c1b740 objtool, modules: Discard objtool annotation sections for modules

These two fixes related to the module loading regression introduced by the recent 
objtool changes.

 Thanks,

	Ingo

------------------>
Josh Poimboeuf (2):
      objtool, compiler.h: Fix __unreachable section relocation size
      objtool, modules: Discard objtool annotation sections for modules


 arch/x86/kernel/vmlinux.lds.S | 2 --
 include/linux/compiler-gcc.h  | 4 ++--
 include/linux/frame.h         | 2 +-
 scripts/mod/modpost.c         | 1 +
 scripts/module-common.lds     | 5 ++++-
 tools/objtool/builtin-check.c | 6 +++---
 6 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index ad0118fbce90..c74ae9ce8dc4 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -345,8 +345,6 @@ SECTIONS
 	DISCARDS
 	/DISCARD/ : {
 		*(.eh_frame)
-		*(__func_stack_frame_non_standard)
-		*(__unreachable)
 	}
 }
 
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 76e28c229805..0efef9cf014f 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -200,8 +200,8 @@
 #ifdef CONFIG_STACK_VALIDATION
 #define annotate_unreachable() ({					\
 	asm("%c0:\t\n"							\
-	    ".pushsection __unreachable, \"a\"\t\n"			\
-	    ".long %c0b\t\n"						\
+	    ".pushsection .discard.unreachable\t\n"			\
+	    ".long %c0b - .\t\n"					\
 	    ".popsection\t\n" : : "i" (__LINE__));			\
 })
 #else
diff --git a/include/linux/frame.h b/include/linux/frame.h
index e6baaba3f1ae..d772c61c31da 100644
--- a/include/linux/frame.h
+++ b/include/linux/frame.h
@@ -11,7 +11,7 @@
  * For more information, see tools/objtool/Documentation/stack-validation.txt.
  */
 #define STACK_FRAME_NON_STANDARD(func) \
-	static void __used __section(__func_stack_frame_non_standard) \
+	static void __used __section(.discard.func_stack_frame_non_standard) \
 		*__func_stack_frame_non_standard_##func = func
 
 #else /* !CONFIG_STACK_VALIDATION */
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 4dedd0d3d3a7..30d752a4a6a6 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -854,6 +854,7 @@ static const char *const section_white_list[] =
 	".cmem*",			/* EZchip */
 	".fmt_slot*",			/* EZchip */
 	".gnu.lto*",
+	".discard.*",
 	NULL
 };
 
diff --git a/scripts/module-common.lds b/scripts/module-common.lds
index 73a2c7da0e55..cf7e52e4781b 100644
--- a/scripts/module-common.lds
+++ b/scripts/module-common.lds
@@ -4,7 +4,10 @@
  * combine them automatically.
  */
 SECTIONS {
-	/DISCARD/ : { *(.discard) }
+	/DISCARD/ : {
+		*(.discard)
+		*(.discard.*)
+	}
 
 	__ksymtab		0 : { *(SORT(___ksymtab+*)) }
 	__ksymtab_gpl		0 : { *(SORT(___ksymtab_gpl+*)) }
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index 5fc52ee3264c..4cfdbb5b6967 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -339,13 +339,13 @@ static int add_dead_ends(struct objtool_file *file)
 	struct instruction *insn;
 	bool found;
 
-	sec = find_section_by_name(file->elf, ".rela__unreachable");
+	sec = find_section_by_name(file->elf, ".rela.discard.unreachable");
 	if (!sec)
 		return 0;
 
 	list_for_each_entry(rela, &sec->rela_list, list) {
 		if (rela->sym->type != STT_SECTION) {
-			WARN("unexpected relocation symbol type in .rela__unreachable");
+			WARN("unexpected relocation symbol type in %s", sec->name);
 			return -1;
 		}
 		insn = find_insn(file, rela->sym->sec, rela->addend);
@@ -1272,7 +1272,7 @@ int cmd_check(int argc, const char **argv)
 
 	INIT_LIST_HEAD(&file.insn_list);
 	hash_init(file.insn_hash);
-	file.whitelist = find_section_by_name(file.elf, "__func_stack_frame_non_standard");
+	file.whitelist = find_section_by_name(file.elf, ".discard.func_stack_frame_non_standard");
 	file.rodata = find_section_by_name(file.elf, ".rodata");
 	file.ignore_unreachables = false;
 	file.c_file = find_section_by_name(file.elf, ".comment");

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [GIT PULL] objtool fixes
  2017-03-01  1:55 ` Linus Torvalds
@ 2017-03-01  6:05   ` Josh Poimboeuf
  0 siblings, 0 replies; 16+ messages in thread
From: Josh Poimboeuf @ 2017-03-01  6:05 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Ingo Molnar, Linux Kernel Mailing List, Thomas Gleixner,
	H. Peter Anvin, Peter Zijlstra

On Tue, Feb 28, 2017 at 05:55:11PM -0800, Linus Torvalds wrote:
> Guys,
>  the recent 'objtool' pull request broke things.
> 
> I haven't bisected it, but I'm pretty sure that this part is pure garbage:
> 
> On Mon, Feb 27, 2017 at 11:53 PM, Ingo Molnar <mingo@kernel.org> wrote:
> >
> > diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
> > index e79f15f108a8..ad0118fbce90 100644
> > --- a/arch/x86/kernel/vmlinux.lds.S
> > +++ b/arch/x86/kernel/vmlinux.lds.S
> > @@ -346,6 +346,7 @@ SECTIONS
> >         /DISCARD/ : {
> >                 *(.eh_frame)
> >                 *(__func_stack_frame_non_standard)
> > +               *(__unreachable)
> >         }
> >  }
> >
> > diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
> > index 0444b1336268..f457b520ead6 100644
> > --- a/include/linux/compiler-gcc.h
> > +++ b/include/linux/compiler-gcc.h
> > @@ -195,6 +195,17 @@
> >  #endif
> >  #endif
> >
> > +#ifdef CONFIG_STACK_VALIDATION
> > +#define annotate_unreachable() ({                                      \
> > +       asm("%c0:\t\n"                                                  \
> > +           ".pushsection __unreachable, \"a\"\t\n"                     \
> > +           ".long %c0b\t\n"                                            \
> > +           ".popsection\t\n" : : "i" (__LINE__));                      \
> > +})
> > +#else
> > +#define annotate_unreachable()
> > +#endif
> 
> and I think the above is what breaks module loading for me right now
> on my laptop.
> 
> I get this during bootup:
> 
>     module: overflow in relocation type 10 val ffffffffc02afc81
>     module: 'nvme' likely not compiled with -mcmodel=kernel
> 
> (and similar errors for other modules too), but those modules very
> much *are* compiled with all the normal kernel build flags, including
> -mcmodel=kernel.
> 
> Now, relocation type 10 is R_X86_64_32, so the warning is very true:
> that address would fit in a _signed_ 32-bit value, but that's
> supposedly a 32-bit unsigned relocation.
> 
> Trying to figure out what the hell is going on, I do:
> 
>     objdump -r nvme.ko | grep 64_32
> 
> and what do I find? I find
> 
>   RELOCATION RECORDS FOR [__unreachable]:
>   OFFSET           TYPE              VALUE
>   0000000000000000 R_X86_64_32       .text+0x0000000000000c81
>   0000000000000004 R_X86_64_32       .text+0x0000000000000cb5
>   0000000000000008 R_X86_64_32       .text+0x0000000000001a18
>   000000000000000c R_X86_64_32       .text+0x0000000000001a36
>   0000000000000010 R_X86_64_32       .text+0x0000000000001e38
>   0000000000000014 R_X86_64_32       .text+0x0000000000001ec2
>   0000000000000018 R_X86_64_32       .text+0x00000000000034e2
>   000000000000001c R_X86_64_32       .text+0x0000000000003536
> 
> and then when I look more closely (objdump --disassemble), I see that
> the offset 000c81 in the module refers to this:
> 
>   0000000000000c60 <nvme_admin_init_request>:
>         ....
>      c7f:       0f 0b                   ud2
>      c81:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)
> 
> so it very much looks like those relocations are still around on
> modules, and so module loading fails.
> 
> Anyway, those annotations are completely bogus anyway, it looks. You
> guys should use relative offsets in order to be able to specify a
> kernel address. So doing
> 
>     .long %c0
> 
> is garbage - either it needs to be a .quad, or it needs to be relative
> to the text section to fit in a .long.
> 
> Hmm? Revert or fix, but please quickly...

Yuck, sorry about that.  Patch to fix it below.

This also highlights another (minor) issue: the '__unreachable' section
is meant to be a compile-time-only thing.  It's supposed to be discarded
at link time, but apparently that isn't happening for modules.

I tried excluding it from linking with the .pushsection "e" flag, but no
luck.  I'll try to figure out how to fix that shortly.

In the meantime, here's the fix you need.  It now uses X86_64_64
relocations.

----

From: Josh Poimboeuf <jpoimboe@redhat.com>
Subject: [PATCH] objtool: fix __unreachable section relocation size

Linus reported the following commit broke module loading on his laptop:

  d1091c7fa3d5 ("objtool: Improve detection of BUG() and other dead ends")

It showed errors like the following:

  module: overflow in relocation type 10 val ffffffffc02afc81
  module: 'nvme' likely not compiled with -mcmodel=kernel

The problem is that the __unreachable section addresses are stored using
the '.long' asm directive, which isn't big enough for .text section
relative kernel addresses.  Use '.quad' instead.

Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Fixes: d1091c7fa3d5 ("objtool: Improve detection of BUG() and other dead ends")
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
 include/linux/compiler-gcc.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index f457b520..7bd21e8 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -199,7 +199,7 @@
 #define annotate_unreachable() ({					\
 	asm("%c0:\t\n"							\
 	    ".pushsection __unreachable, \"a\"\t\n"			\
-	    ".long %c0b\t\n"						\
+	    ".quad %c0b\t\n"						\
 	    ".popsection\t\n" : : "i" (__LINE__));			\
 })
 #else
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [GIT PULL] objtool fixes
  2017-02-28  7:53 Ingo Molnar
@ 2017-03-01  1:55 ` Linus Torvalds
  2017-03-01  6:05   ` Josh Poimboeuf
  0 siblings, 1 reply; 16+ messages in thread
From: Linus Torvalds @ 2017-03-01  1:55 UTC (permalink / raw)
  To: Ingo Molnar, Josh Poimboeuf
  Cc: Linux Kernel Mailing List, Thomas Gleixner, H. Peter Anvin,
	Peter Zijlstra

Guys,
 the recent 'objtool' pull request broke things.

I haven't bisected it, but I'm pretty sure that this part is pure garbage:

On Mon, Feb 27, 2017 at 11:53 PM, Ingo Molnar <mingo@kernel.org> wrote:
>
> diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
> index e79f15f108a8..ad0118fbce90 100644
> --- a/arch/x86/kernel/vmlinux.lds.S
> +++ b/arch/x86/kernel/vmlinux.lds.S
> @@ -346,6 +346,7 @@ SECTIONS
>         /DISCARD/ : {
>                 *(.eh_frame)
>                 *(__func_stack_frame_non_standard)
> +               *(__unreachable)
>         }
>  }
>
> diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
> index 0444b1336268..f457b520ead6 100644
> --- a/include/linux/compiler-gcc.h
> +++ b/include/linux/compiler-gcc.h
> @@ -195,6 +195,17 @@
>  #endif
>  #endif
>
> +#ifdef CONFIG_STACK_VALIDATION
> +#define annotate_unreachable() ({                                      \
> +       asm("%c0:\t\n"                                                  \
> +           ".pushsection __unreachable, \"a\"\t\n"                     \
> +           ".long %c0b\t\n"                                            \
> +           ".popsection\t\n" : : "i" (__LINE__));                      \
> +})
> +#else
> +#define annotate_unreachable()
> +#endif

and I think the above is what breaks module loading for me right now
on my laptop.

I get this during bootup:

    module: overflow in relocation type 10 val ffffffffc02afc81
    module: 'nvme' likely not compiled with -mcmodel=kernel

(and similar errors for other modules too), but those modules very
much *are* compiled with all the normal kernel build flags, including
-mcmodel=kernel.

Now, relocation type 10 is R_X86_64_32, so the warning is very true:
that address would fit in a _signed_ 32-bit value, but that's
supposedly a 32-bit unsigned relocation.

Trying to figure out what the hell is going on, I do:

    objdump -r nvme.ko | grep 64_32

and what do I find? I find

  RELOCATION RECORDS FOR [__unreachable]:
  OFFSET           TYPE              VALUE
  0000000000000000 R_X86_64_32       .text+0x0000000000000c81
  0000000000000004 R_X86_64_32       .text+0x0000000000000cb5
  0000000000000008 R_X86_64_32       .text+0x0000000000001a18
  000000000000000c R_X86_64_32       .text+0x0000000000001a36
  0000000000000010 R_X86_64_32       .text+0x0000000000001e38
  0000000000000014 R_X86_64_32       .text+0x0000000000001ec2
  0000000000000018 R_X86_64_32       .text+0x00000000000034e2
  000000000000001c R_X86_64_32       .text+0x0000000000003536

and then when I look more closely (objdump --disassemble), I see that
the offset 000c81 in the module refers to this:

  0000000000000c60 <nvme_admin_init_request>:
        ....
     c7f:       0f 0b                   ud2
     c81:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

so it very much looks like those relocations are still around on
modules, and so module loading fails.

Anyway, those annotations are completely bogus anyway, it looks. You
guys should use relative offsets in order to be able to specify a
kernel address. So doing

    .long %c0

is garbage - either it needs to be a .quad, or it needs to be relative
to the text section to fit in a .long.

Hmm? Revert or fix, but please quickly...

                   Linus

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [GIT PULL] objtool fixes
@ 2017-02-28  7:53 Ingo Molnar
  2017-03-01  1:55 ` Linus Torvalds
  0 siblings, 1 reply; 16+ messages in thread
From: Ingo Molnar @ 2017-02-28  7:53 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-kernel, Josh Poimboeuf, Thomas Gleixner, H. Peter Anvin,
	Peter Zijlstra

Linus,

Please pull the latest core-urgent-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-urgent-for-linus

   # HEAD: 4e4636cf981b5b629fbfb78aa9f232e015f7d521 objtool: Enclose contents of unreachable() macro in a block

A handful of objtool fixes related to unreachable code, plus a build fix for out 
of tree modules.

 Thanks,

	Ingo

------------------>
Josh Poimboeuf (4):
      objtool: Fix CONFIG_STACK_VALIDATION=y warning for out-of-tree modules
      objtool: Improve detection of BUG() and other dead ends
      objtool: Prevent GCC from merging annotate_unreachable()
      objtool: Enclose contents of unreachable() macro in a block


 Makefile                        | 24 ++++++++---------
 arch/x86/kernel/vmlinux.lds.S   |  1 +
 include/linux/compiler-gcc.h    | 14 +++++++++-
 tools/objtool/arch.h            |  5 ++--
 tools/objtool/arch/x86/decode.c |  3 ---
 tools/objtool/builtin-check.c   | 60 ++++++++++++++++++++++++++++++++++++++---
 6 files changed, 84 insertions(+), 23 deletions(-)

diff --git a/Makefile b/Makefile
index f1e6a02a0c19..32c84577aa93 100644
--- a/Makefile
+++ b/Makefile
@@ -908,6 +908,18 @@ mod_sign_cmd = true
 endif
 export mod_sign_cmd
 
+ifdef CONFIG_STACK_VALIDATION
+  has_libelf := $(call try-run,\
+		echo "int main() {}" | $(HOSTCC) -xc -o /dev/null -lelf -,1,0)
+  ifeq ($(has_libelf),1)
+    objtool_target := tools/objtool FORCE
+  else
+    $(warning "Cannot use CONFIG_STACK_VALIDATION, please install libelf-dev, libelf-devel or elfutils-libelf-devel")
+    SKIP_STACK_VALIDATION := 1
+    export SKIP_STACK_VALIDATION
+  endif
+endif
+
 
 ifeq ($(KBUILD_EXTMOD),)
 core-y		+= kernel/ certs/ mm/ fs/ ipc/ security/ crypto/ block/
@@ -1035,18 +1047,6 @@ prepare0: archprepare gcc-plugins
 # All the preparing..
 prepare: prepare0 prepare-objtool
 
-ifdef CONFIG_STACK_VALIDATION
-  has_libelf := $(call try-run,\
-		echo "int main() {}" | $(HOSTCC) -xc -o /dev/null -lelf -,1,0)
-  ifeq ($(has_libelf),1)
-    objtool_target := tools/objtool FORCE
-  else
-    $(warning "Cannot use CONFIG_STACK_VALIDATION, please install libelf-dev, libelf-devel or elfutils-libelf-devel")
-    SKIP_STACK_VALIDATION := 1
-    export SKIP_STACK_VALIDATION
-  endif
-endif
-
 PHONY += prepare-objtool
 prepare-objtool: $(objtool_target)
 
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index e79f15f108a8..ad0118fbce90 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -346,6 +346,7 @@ SECTIONS
 	/DISCARD/ : {
 		*(.eh_frame)
 		*(__func_stack_frame_non_standard)
+		*(__unreachable)
 	}
 }
 
diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
index 0444b1336268..f457b520ead6 100644
--- a/include/linux/compiler-gcc.h
+++ b/include/linux/compiler-gcc.h
@@ -195,6 +195,17 @@
 #endif
 #endif
 
+#ifdef CONFIG_STACK_VALIDATION
+#define annotate_unreachable() ({					\
+	asm("%c0:\t\n"							\
+	    ".pushsection __unreachable, \"a\"\t\n"			\
+	    ".long %c0b\t\n"						\
+	    ".popsection\t\n" : : "i" (__LINE__));			\
+})
+#else
+#define annotate_unreachable()
+#endif
+
 /*
  * Mark a position in code as unreachable.  This can be used to
  * suppress control flow warnings after asm blocks that transfer
@@ -204,7 +215,8 @@
  * this in the preprocessor, but we can live with this because they're
  * unreleased.  Really, we need to have autoconf for the kernel.
  */
-#define unreachable() __builtin_unreachable()
+#define unreachable() \
+	do { annotate_unreachable(); __builtin_unreachable(); } while (0)
 
 /* Mark a function definition as prohibited from being cloned. */
 #define __noclone	__attribute__((__noclone__, __optimize__("no-tracer")))
diff --git a/tools/objtool/arch.h b/tools/objtool/arch.h
index f7350fcedc70..a59e061c0b4a 100644
--- a/tools/objtool/arch.h
+++ b/tools/objtool/arch.h
@@ -31,9 +31,8 @@
 #define INSN_CALL_DYNAMIC	8
 #define INSN_RETURN		9
 #define INSN_CONTEXT_SWITCH	10
-#define INSN_BUG		11
-#define INSN_NOP		12
-#define INSN_OTHER		13
+#define INSN_NOP		11
+#define INSN_OTHER		12
 #define INSN_LAST		INSN_OTHER
 
 int arch_decode_instruction(struct elf *elf, struct section *sec,
diff --git a/tools/objtool/arch/x86/decode.c b/tools/objtool/arch/x86/decode.c
index 039636ffb6c8..6ac99e3266eb 100644
--- a/tools/objtool/arch/x86/decode.c
+++ b/tools/objtool/arch/x86/decode.c
@@ -118,9 +118,6 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
 			 op2 == 0x35)
 			/* sysenter, sysret */
 			*type = INSN_CONTEXT_SWITCH;
-		else if (op2 == 0x0b || op2 == 0xb9)
-			/* ud2 */
-			*type = INSN_BUG;
 		else if (op2 == 0x0d || op2 == 0x1f)
 			/* nopl/nopw */
 			*type = INSN_NOP;
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index e8a1f699058a..5fc52ee3264c 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -51,7 +51,7 @@ struct instruction {
 	unsigned int len, state;
 	unsigned char type;
 	unsigned long immediate;
-	bool alt_group, visited;
+	bool alt_group, visited, dead_end;
 	struct symbol *call_dest;
 	struct instruction *jump_dest;
 	struct list_head alts;
@@ -330,6 +330,54 @@ static int decode_instructions(struct objtool_file *file)
 }
 
 /*
+ * Find all uses of the unreachable() macro, which are code path dead ends.
+ */
+static int add_dead_ends(struct objtool_file *file)
+{
+	struct section *sec;
+	struct rela *rela;
+	struct instruction *insn;
+	bool found;
+
+	sec = find_section_by_name(file->elf, ".rela__unreachable");
+	if (!sec)
+		return 0;
+
+	list_for_each_entry(rela, &sec->rela_list, list) {
+		if (rela->sym->type != STT_SECTION) {
+			WARN("unexpected relocation symbol type in .rela__unreachable");
+			return -1;
+		}
+		insn = find_insn(file, rela->sym->sec, rela->addend);
+		if (insn)
+			insn = list_prev_entry(insn, list);
+		else if (rela->addend == rela->sym->sec->len) {
+			found = false;
+			list_for_each_entry_reverse(insn, &file->insn_list, list) {
+				if (insn->sec == rela->sym->sec) {
+					found = true;
+					break;
+				}
+			}
+
+			if (!found) {
+				WARN("can't find unreachable insn at %s+0x%x",
+				     rela->sym->sec->name, rela->addend);
+				return -1;
+			}
+		} else {
+			WARN("can't find unreachable insn at %s+0x%x",
+			     rela->sym->sec->name, rela->addend);
+			return -1;
+		}
+
+		insn->dead_end = true;
+	}
+
+	return 0;
+}
+
+/*
  * Warnings shouldn't be reported for ignored functions.
  */
 static void add_ignores(struct objtool_file *file)
@@ -843,6 +891,10 @@ static int decode_sections(struct objtool_file *file)
 	if (ret)
 		return ret;
 
+	ret = add_dead_ends(file);
+	if (ret)
+		return ret;
+
 	add_ignores(file);
 
 	ret = add_jump_destinations(file);
@@ -1037,13 +1089,13 @@ static int validate_branch(struct objtool_file *file,
 
 			return 0;
 
-		case INSN_BUG:
-			return 0;
-
 		default:
 			break;
 		}
 
+		if (insn->dead_end)
+			return 0;
+
 		insn = next_insn_same_sec(file, insn);
 		if (!insn) {
 			WARN("%s: unexpected end of section", sec->name);

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [GIT PULL] objtool fixes
@ 2016-04-23 11:10 Ingo Molnar
  0 siblings, 0 replies; 16+ messages in thread
From: Ingo Molnar @ 2016-04-23 11:10 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: linux-kernel, Peter Zijlstra, Thomas Gleixner, Andrew Morton,
	Arnaldo Carvalho de Melo, Jiri Olsa, Josh Poimboeuf

Linus,

Please pull the latest core-urgent-for-linus git tree from:

   git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git core-urgent-for-linus

   # HEAD: c2bb9e32e2315971a8535fee77335c04a739d71d objtool: Fix Makefile to properly see if libelf is supported

A handful of objtool fixes: two improvements to how warnings are printed plus a 
false positive warning fix, and build environment fix.

 Thanks,

	Ingo

------------------>
Josh Poimboeuf (2):
      objtool: Add workaround for GCC switch jump table bug
      objtool: Detect falling through to the next function

Steven Rostedt (1):
      objtool: Fix Makefile to properly see if libelf is supported


 Makefile                                         |  3 +-
 tools/objtool/Documentation/stack-validation.txt | 38 +++++++---
 tools/objtool/builtin-check.c                    | 97 ++++++++++++++++++------
 3 files changed, 103 insertions(+), 35 deletions(-)

diff --git a/Makefile b/Makefile
index 1d0aef03eae7..70ca38ef9f4b 100644
--- a/Makefile
+++ b/Makefile
@@ -1008,7 +1008,8 @@ prepare0: archprepare FORCE
 prepare: prepare0 prepare-objtool
 
 ifdef CONFIG_STACK_VALIDATION
-  has_libelf := $(shell echo "int main() {}" | $(HOSTCC) -xc -o /dev/null -lelf - &> /dev/null && echo 1 || echo 0)
+  has_libelf := $(call try-run,\
+		echo "int main() {}" | $(HOSTCC) -xc -o /dev/null -lelf -,1,0)
   ifeq ($(has_libelf),1)
     objtool_target := tools/objtool FORCE
   else
diff --git a/tools/objtool/Documentation/stack-validation.txt b/tools/objtool/Documentation/stack-validation.txt
index 5a95896105bc..55a60d331f47 100644
--- a/tools/objtool/Documentation/stack-validation.txt
+++ b/tools/objtool/Documentation/stack-validation.txt
@@ -299,18 +299,38 @@ they mean, and suggestions for how to fix them.
 Errors in .c files
 ------------------
 
-If you're getting an objtool error in a compiled .c file, chances are
-the file uses an asm() statement which has a "call" instruction.  An
-asm() statement with a call instruction must declare the use of the
-stack pointer in its output operand.  For example, on x86_64:
+1. c_file.o: warning: objtool: funcA() falls through to next function funcB()
 
-   register void *__sp asm("rsp");
-   asm volatile("call func" : "+r" (__sp));
+   This means that funcA() doesn't end with a return instruction or an
+   unconditional jump, and that objtool has determined that the function
+   can fall through into the next function.  There could be different
+   reasons for this:
 
-Otherwise the stack frame may not get created before the call.
+   1) funcA()'s last instruction is a call to a "noreturn" function like
+      panic().  In this case the noreturn function needs to be added to
+      objtool's hard-coded global_noreturns array.  Feel free to bug the
+      objtool maintainer, or you can submit a patch.
 
-Another possible cause for errors in C code is if the Makefile removes
--fno-omit-frame-pointer or adds -fomit-frame-pointer to the gcc options.
+   2) funcA() uses the unreachable() annotation in a section of code
+      that is actually reachable.
+
+   3) If funcA() calls an inline function, the object code for funcA()
+      might be corrupt due to a gcc bug.  For more details, see:
+      https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70646
+
+2. If you're getting any other objtool error in a compiled .c file, it
+   may be because the file uses an asm() statement which has a "call"
+   instruction.  An asm() statement with a call instruction must declare
+   the use of the stack pointer in its output operand.  For example, on
+   x86_64:
+
+     register void *__sp asm("rsp");
+     asm volatile("call func" : "+r" (__sp));
+
+   Otherwise the stack frame may not get created before the call.
+
+3. Another possible cause for errors in C code is if the Makefile removes
+   -fno-omit-frame-pointer or adds -fomit-frame-pointer to the gcc options.
 
 Also see the above section for .S file errors for more information what
 the individual error messages mean.
diff --git a/tools/objtool/builtin-check.c b/tools/objtool/builtin-check.c
index 7515cb2e879a..e8a1e69eb92c 100644
--- a/tools/objtool/builtin-check.c
+++ b/tools/objtool/builtin-check.c
@@ -54,6 +54,7 @@ struct instruction {
 	struct symbol *call_dest;
 	struct instruction *jump_dest;
 	struct list_head alts;
+	struct symbol *func;
 };
 
 struct alternative {
@@ -66,6 +67,7 @@ struct objtool_file {
 	struct list_head insn_list;
 	DECLARE_HASHTABLE(insn_hash, 16);
 	struct section *rodata, *whitelist;
+	bool ignore_unreachables, c_file;
 };
 
 const char *objname;
@@ -228,7 +230,7 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
 			}
 		}
 
-		if (insn->type == INSN_JUMP_DYNAMIC)
+		if (insn->type == INSN_JUMP_DYNAMIC && list_empty(&insn->alts))
 			/* sibling call */
 			return 0;
 	}
@@ -248,6 +250,7 @@ static int dead_end_function(struct objtool_file *file, struct symbol *func)
 static int decode_instructions(struct objtool_file *file)
 {
 	struct section *sec;
+	struct symbol *func;
 	unsigned long offset;
 	struct instruction *insn;
 	int ret;
@@ -281,6 +284,21 @@ static int decode_instructions(struct objtool_file *file)
 			hash_add(file->insn_hash, &insn->hash, insn->offset);
 			list_add_tail(&insn->list, &file->insn_list);
 		}
+
+		list_for_each_entry(func, &sec->symbol_list, list) {
+			if (func->type != STT_FUNC)
+				continue;
+
+			if (!find_insn(file, sec, func->offset)) {
+				WARN("%s(): can't find starting instruction",
+				     func->name);
+				return -1;
+			}
+
+			func_for_each_insn(file, func, insn)
+				if (!insn->func)
+					insn->func = func;
+		}
 	}
 
 	return 0;
@@ -664,13 +682,40 @@ static int add_func_switch_tables(struct objtool_file *file,
 						text_rela->addend);
 
 		/*
-		 * TODO: Document where this is needed, or get rid of it.
-		 *
 		 * rare case:   jmpq *[addr](%rip)
+		 *
+		 * This check is for a rare gcc quirk, currently only seen in
+		 * three driver functions in the kernel, only with certain
+		 * obscure non-distro configs.
+		 *
+		 * As part of an optimization, gcc makes a copy of an existing
+		 * switch jump table, modifies it, and then hard-codes the jump
+		 * (albeit with an indirect jump) to use a single entry in the
+		 * table.  The rest of the jump table and some of its jump
+		 * targets remain as dead code.
+		 *
+		 * In such a case we can just crudely ignore all unreachable
+		 * instruction warnings for the entire object file.  Ideally we
+		 * would just ignore them for the function, but that would
+		 * require redesigning the code quite a bit.  And honestly
+		 * that's just not worth doing: unreachable instruction
+		 * warnings are of questionable value anyway, and this is such
+		 * a rare issue.
+		 *
+		 * kbuild reports:
+		 * - https://lkml.kernel.org/r/201603231906.LWcVUpxm%25fengguang.wu@intel.com
+		 * - https://lkml.kernel.org/r/201603271114.K9i45biy%25fengguang.wu@intel.com
+		 * - https://lkml.kernel.org/r/201603291058.zuJ6ben1%25fengguang.wu@intel.com
+		 *
+		 * gcc bug:
+		 * - https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70604
 		 */
-		if (!rodata_rela)
+		if (!rodata_rela) {
 			rodata_rela = find_rela_by_dest(file->rodata,
 							text_rela->addend + 4);
+			if (rodata_rela)
+				file->ignore_unreachables = true;
+		}
 
 		if (!rodata_rela)
 			continue;
@@ -732,9 +777,6 @@ static int decode_sections(struct objtool_file *file)
 {
 	int ret;
 
-	file->whitelist = find_section_by_name(file->elf, "__func_stack_frame_non_standard");
-	file->rodata = find_section_by_name(file->elf, ".rodata");
-
 	ret = decode_instructions(file);
 	if (ret)
 		return ret;
@@ -799,6 +841,7 @@ static int validate_branch(struct objtool_file *file,
 	struct alternative *alt;
 	struct instruction *insn;
 	struct section *sec;
+	struct symbol *func = NULL;
 	unsigned char state;
 	int ret;
 
@@ -813,6 +856,16 @@ static int validate_branch(struct objtool_file *file,
 	}
 
 	while (1) {
+		if (file->c_file && insn->func) {
+			if (func && func != insn->func) {
+				WARN("%s() falls through to next function %s()",
+				     func->name, insn->func->name);
+				return 1;
+			}
+
+			func = insn->func;
+		}
+
 		if (insn->visited) {
 			if (frame_state(insn->state) != frame_state(state)) {
 				WARN_FUNC("frame pointer state mismatch",
@@ -823,13 +876,6 @@ static int validate_branch(struct objtool_file *file,
 			return 0;
 		}
 
-		/*
-		 * Catch a rare case where a noreturn function falls through to
-		 * the next function.
-		 */
-		if (is_fentry_call(insn) && (state & STATE_FENTRY))
-			return 0;
-
 		insn->visited = true;
 		insn->state = state;
 
@@ -1035,12 +1081,8 @@ static int validate_functions(struct objtool_file *file)
 				continue;
 
 			insn = find_insn(file, sec, func->offset);
-			if (!insn) {
-				WARN("%s(): can't find starting instruction",
-				     func->name);
-				warnings++;
+			if (!insn)
 				continue;
-			}
 
 			ret = validate_branch(file, insn, 0);
 			warnings += ret;
@@ -1056,13 +1098,14 @@ static int validate_functions(struct objtool_file *file)
 				if (insn->visited)
 					continue;
 
-				if (!ignore_unreachable_insn(func, insn) &&
-				    !warnings) {
-					WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset);
-					warnings++;
-				}
-
 				insn->visited = true;
+
+				if (file->ignore_unreachables || warnings ||
+				    ignore_unreachable_insn(func, insn))
+					continue;
+
+				WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset);
+				warnings++;
 			}
 		}
 	}
@@ -1133,6 +1176,10 @@ int cmd_check(int argc, const char **argv)
 
 	INIT_LIST_HEAD(&file.insn_list);
 	hash_init(file.insn_hash);
+	file.whitelist = find_section_by_name(file.elf, "__func_stack_frame_non_standard");
+	file.rodata = find_section_by_name(file.elf, ".rodata");
+	file.ignore_unreachables = false;
+	file.c_file = find_section_by_name(file.elf, ".comment");
 
 	ret = decode_sections(&file);
 	if (ret < 0)

^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2021-06-24 16:34 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-25  9:04 [GIT PULL] objtool fixes Ingo Molnar
2020-04-25 19:30 ` pr-tracker-bot
  -- strict thread matches above, loose matches on Subject: below --
2021-06-24  6:54 Ingo Molnar
2021-06-24 16:34 ` pr-tracker-bot
2021-06-12 12:37 Ingo Molnar
2021-06-12 19:09 ` pr-tracker-bot
2021-05-15  7:46 Ingo Molnar
2021-05-15 17:55 ` pr-tracker-bot
2018-11-30  6:18 Ingo Molnar
2018-11-30 21:00 ` pr-tracker-bot
2017-11-26 12:34 Ingo Molnar
2017-03-01 22:01 Ingo Molnar
2017-02-28  7:53 Ingo Molnar
2017-03-01  1:55 ` Linus Torvalds
2017-03-01  6:05   ` Josh Poimboeuf
2016-04-23 11:10 Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).