All of lore.kernel.org
 help / color / mirror / Atom feed
* Kernel build with gcc 8 a lot of warnings
@ 2018-05-05 19:21 damian
  2018-05-07  4:54 ` Josh Poimboeuf
  2018-05-09 14:27 ` David Laight
  0 siblings, 2 replies; 14+ messages in thread
From: damian @ 2018-05-05 19:21 UTC (permalink / raw)
  To: jpoimboe, peterz; +Cc: linux-kernel

Helllo together,

Hello everybody,

is something special to note when kernel build with gcc 8? I receive various warnings from the objtool:
With GCC 7 works all fine.

kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x40: sibling call from callable instruction with modified stack frame
kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x2a3: sibling call from callable instruction with modified stack frame
kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x20b: sibling call from callable instruction with modified stack frame
kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x296: sibling call from callable instruction with modified stack frame
kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable()+0x10: sibling call from callable instruction with modified stack frame
kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags.cold.45()+0xa: call without frame pointer save/setup
kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files.cold.46()+0x17: call without frame pointer save/setup
kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable.cold.47()+0x24: call without frame pointer save/setup
kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems.cold.48()+0x10: call without frame pointer save/setup
kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable.cold.49()+0x7: call without frame pointer save/setup
  CC      kernel/cgroup/stat.o
  CC [M]  arch/x86/kvm/../../../virt/kvm/kvm_main.o
arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic()+0x10: sibling call from callable instruction with modified stack frame
arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu()+0x2c: sibling call from callable instruction with modified stack frame
arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic.cold.6()+0x7: call without frame pointer save/setup
arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu.cold.7()+0x7: call without frame pointer save/setup

Best regards
Damian

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

* Re: Kernel build with gcc 8 a lot of warnings
  2018-05-05 19:21 Kernel build with gcc 8 a lot of warnings damian
@ 2018-05-07  4:54 ` Josh Poimboeuf
  2018-05-07 10:57   ` damian
  2018-05-08  5:51   ` Greg KH
  2018-05-09 14:27 ` David Laight
  1 sibling, 2 replies; 14+ messages in thread
From: Josh Poimboeuf @ 2018-05-07  4:54 UTC (permalink / raw)
  To: damian; +Cc: peterz, linux-kernel

On Sat, May 05, 2018 at 09:21:12PM +0200, damian wrote:
> Helllo together,
> 
> Hello everybody,
> 
> is something special to note when kernel build with gcc 8? I receive various warnings from the objtool:
> With GCC 7 works all fine.
> 
> kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x40: sibling call from callable instruction with modified stack frame
> kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x2a3: sibling call from callable instruction with modified stack frame
> kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x20b: sibling call from callable instruction with modified stack frame
> kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x296: sibling call from callable instruction with modified stack frame
> kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable()+0x10: sibling call from callable instruction with modified stack frame
> kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags.cold.45()+0xa: call without frame pointer save/setup
> kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files.cold.46()+0x17: call without frame pointer save/setup
> kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable.cold.47()+0x24: call without frame pointer save/setup
> kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems.cold.48()+0x10: call without frame pointer save/setup
> kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable.cold.49()+0x7: call without frame pointer save/setup
>   CC      kernel/cgroup/stat.o
>   CC [M]  arch/x86/kvm/../../../virt/kvm/kvm_main.o
> arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic()+0x10: sibling call from callable instruction with modified stack frame
> arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu()+0x2c: sibling call from callable instruction with modified stack frame
> arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic.cold.6()+0x7: call without frame pointer save/setup
> arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu.cold.7()+0x7: call without frame pointer save/setup

Thanks, this is a known issue with GCC 8 that I haven't gotten a chance
to fix yet.  They're related to the fact that GCC 8 is splitting out
'unlikely' code into 'cold' subfunctions in .text.unlikely.

I've got some old patches that fix it.  Now that GCC 8 is out, I'll need
get the patches dusted off and cleaned up for merging.

-- 
Josh

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

* Re: Kernel build with gcc 8 a lot of warnings
  2018-05-07  4:54 ` Josh Poimboeuf
@ 2018-05-07 10:57   ` damian
  2018-05-08  5:51   ` Greg KH
  1 sibling, 0 replies; 14+ messages in thread
From: damian @ 2018-05-07 10:57 UTC (permalink / raw)
  To: Josh Poimboeuf; +Cc: peterz, linux-kernel

On Sun, 06. May 23:54, Josh Poimboeuf wrote:
> On Sat, May 05, 2018 at 09:21:12PM +0200, damian wrote:
> > Helllo together,
> > 
> > Hello everybody,
> > 
> > is something special to note when kernel build with gcc 8? I receive various warnings from the objtool:
> > With GCC 7 works all fine.
> > 
> > kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x40: sibling call from callable instruction with modified stack frame
> > kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x2a3: sibling call from callable instruction with modified stack frame
> > kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x20b: sibling call from callable instruction with modified stack frame
> > kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x296: sibling call from callable instruction with modified stack frame
> > kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable()+0x10: sibling call from callable instruction with modified stack frame
> > kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags.cold.45()+0xa: call without frame pointer save/setup
> > kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files.cold.46()+0x17: call without frame pointer save/setup
> > kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable.cold.47()+0x24: call without frame pointer save/setup
> > kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems.cold.48()+0x10: call without frame pointer save/setup
> > kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable.cold.49()+0x7: call without frame pointer save/setup
> >   CC      kernel/cgroup/stat.o
> >   CC [M]  arch/x86/kvm/../../../virt/kvm/kvm_main.o
> > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic()+0x10: sibling call from callable instruction with modified stack frame
> > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu()+0x2c: sibling call from callable instruction with modified stack frame
> > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic.cold.6()+0x7: call without frame pointer save/setup
> > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu.cold.7()+0x7: call without frame pointer save/setup
> 
> Thanks, this is a known issue with GCC 8 that I haven't gotten a chance
> to fix yet.  They're related to the fact that GCC 8 is splitting out
> 'unlikely' code into 'cold' subfunctions in .text.unlikely.
> 
> I've got some old patches that fix it.  Now that GCC 8 is out, I'll need
> get the patches dusted off and cleaned up for merging.
> 
> -- 
> Josh

Hello Josh,

if you need any additional information, please feel free and contact me. 

Best regards
Damian

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

* Re: Kernel build with gcc 8 a lot of warnings
  2018-05-07  4:54 ` Josh Poimboeuf
  2018-05-07 10:57   ` damian
@ 2018-05-08  5:51   ` Greg KH
  2018-05-08  5:58     ` Greg KH
  2018-05-08 13:34     ` Josh Poimboeuf
  1 sibling, 2 replies; 14+ messages in thread
From: Greg KH @ 2018-05-08  5:51 UTC (permalink / raw)
  To: Josh Poimboeuf; +Cc: damian, peterz, linux-kernel

On Sun, May 06, 2018 at 11:54:53PM -0500, Josh Poimboeuf wrote:
> On Sat, May 05, 2018 at 09:21:12PM +0200, damian wrote:
> > Helllo together,
> > 
> > Hello everybody,
> > 
> > is something special to note when kernel build with gcc 8? I receive various warnings from the objtool:
> > With GCC 7 works all fine.
> > 
> > kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x40: sibling call from callable instruction with modified stack frame
> > kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x2a3: sibling call from callable instruction with modified stack frame
> > kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x20b: sibling call from callable instruction with modified stack frame
> > kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x296: sibling call from callable instruction with modified stack frame
> > kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable()+0x10: sibling call from callable instruction with modified stack frame
> > kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags.cold.45()+0xa: call without frame pointer save/setup
> > kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files.cold.46()+0x17: call without frame pointer save/setup
> > kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable.cold.47()+0x24: call without frame pointer save/setup
> > kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems.cold.48()+0x10: call without frame pointer save/setup
> > kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable.cold.49()+0x7: call without frame pointer save/setup
> >   CC      kernel/cgroup/stat.o
> >   CC [M]  arch/x86/kvm/../../../virt/kvm/kvm_main.o
> > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic()+0x10: sibling call from callable instruction with modified stack frame
> > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu()+0x2c: sibling call from callable instruction with modified stack frame
> > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic.cold.6()+0x7: call without frame pointer save/setup
> > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu.cold.7()+0x7: call without frame pointer save/setup
> 
> Thanks, this is a known issue with GCC 8 that I haven't gotten a chance
> to fix yet.  They're related to the fact that GCC 8 is splitting out
> 'unlikely' code into 'cold' subfunctions in .text.unlikely.
> 
> I've got some old patches that fix it.  Now that GCC 8 is out, I'll need
> get the patches dusted off and cleaned up for merging.

Any pointers to these patches?  Archi linux just changed their default
compiler to gcc 8 and now I'm seeing this in my local builds :(

thanks,

greg k-h

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

* Re: Kernel build with gcc 8 a lot of warnings
  2018-05-08  5:51   ` Greg KH
@ 2018-05-08  5:58     ` Greg KH
  2018-05-08 13:34     ` Josh Poimboeuf
  1 sibling, 0 replies; 14+ messages in thread
From: Greg KH @ 2018-05-08  5:58 UTC (permalink / raw)
  To: Josh Poimboeuf; +Cc: damian, peterz, linux-kernel

On Tue, May 08, 2018 at 07:51:26AM +0200, Greg KH wrote:
> On Sun, May 06, 2018 at 11:54:53PM -0500, Josh Poimboeuf wrote:
> > On Sat, May 05, 2018 at 09:21:12PM +0200, damian wrote:
> > > Helllo together,
> > > 
> > > Hello everybody,
> > > 
> > > is something special to note when kernel build with gcc 8? I receive various warnings from the objtool:
> > > With GCC 7 works all fine.
> > > 
> > > kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x40: sibling call from callable instruction with modified stack frame
> > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x2a3: sibling call from callable instruction with modified stack frame
> > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x20b: sibling call from callable instruction with modified stack frame
> > > kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x296: sibling call from callable instruction with modified stack frame
> > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable()+0x10: sibling call from callable instruction with modified stack frame
> > > kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags.cold.45()+0xa: call without frame pointer save/setup
> > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files.cold.46()+0x17: call without frame pointer save/setup
> > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable.cold.47()+0x24: call without frame pointer save/setup
> > > kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems.cold.48()+0x10: call without frame pointer save/setup
> > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable.cold.49()+0x7: call without frame pointer save/setup
> > >   CC      kernel/cgroup/stat.o
> > >   CC [M]  arch/x86/kvm/../../../virt/kvm/kvm_main.o
> > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic()+0x10: sibling call from callable instruction with modified stack frame
> > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu()+0x2c: sibling call from callable instruction with modified stack frame
> > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic.cold.6()+0x7: call without frame pointer save/setup
> > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu.cold.7()+0x7: call without frame pointer save/setup
> > 
> > Thanks, this is a known issue with GCC 8 that I haven't gotten a chance
> > to fix yet.  They're related to the fact that GCC 8 is splitting out
> > 'unlikely' code into 'cold' subfunctions in .text.unlikely.
> > 
> > I've got some old patches that fix it.  Now that GCC 8 is out, I'll need
> > get the patches dusted off and cleaned up for merging.
> 
> Any pointers to these patches?  Archi linux just changed their default
> compiler to gcc 8 and now I'm seeing this in my local builds :(

s/Archi/Arch/

ugh, time for more coffee...

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

* Re: Kernel build with gcc 8 a lot of warnings
  2018-05-08  5:51   ` Greg KH
  2018-05-08  5:58     ` Greg KH
@ 2018-05-08 13:34     ` Josh Poimboeuf
  2018-05-08 14:25       ` Greg KH
  1 sibling, 1 reply; 14+ messages in thread
From: Josh Poimboeuf @ 2018-05-08 13:34 UTC (permalink / raw)
  To: Greg KH; +Cc: damian, peterz, linux-kernel

On Tue, May 08, 2018 at 07:51:26AM +0200, Greg KH wrote:
> On Sun, May 06, 2018 at 11:54:53PM -0500, Josh Poimboeuf wrote:
> > On Sat, May 05, 2018 at 09:21:12PM +0200, damian wrote:
> > > Helllo together,
> > > 
> > > Hello everybody,
> > > 
> > > is something special to note when kernel build with gcc 8? I receive various warnings from the objtool:
> > > With GCC 7 works all fine.
> > > 
> > > kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x40: sibling call from callable instruction with modified stack frame
> > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x2a3: sibling call from callable instruction with modified stack frame
> > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x20b: sibling call from callable instruction with modified stack frame
> > > kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x296: sibling call from callable instruction with modified stack frame
> > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable()+0x10: sibling call from callable instruction with modified stack frame
> > > kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags.cold.45()+0xa: call without frame pointer save/setup
> > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files.cold.46()+0x17: call without frame pointer save/setup
> > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable.cold.47()+0x24: call without frame pointer save/setup
> > > kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems.cold.48()+0x10: call without frame pointer save/setup
> > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable.cold.49()+0x7: call without frame pointer save/setup
> > >   CC      kernel/cgroup/stat.o
> > >   CC [M]  arch/x86/kvm/../../../virt/kvm/kvm_main.o
> > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic()+0x10: sibling call from callable instruction with modified stack frame
> > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu()+0x2c: sibling call from callable instruction with modified stack frame
> > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic.cold.6()+0x7: call without frame pointer save/setup
> > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu.cold.7()+0x7: call without frame pointer save/setup
> > 
> > Thanks, this is a known issue with GCC 8 that I haven't gotten a chance
> > to fix yet.  They're related to the fact that GCC 8 is splitting out
> > 'unlikely' code into 'cold' subfunctions in .text.unlikely.
> > 
> > I've got some old patches that fix it.  Now that GCC 8 is out, I'll need
> > get the patches dusted off and cleaned up for merging.
> 
> Any pointers to these patches?  Archi linux just changed their default
> compiler to gcc 8 and now I'm seeing this in my local builds :(

I'm still dusting the code off, but this fixes most of the warnings.
The rest of the code should hopefully be ready soon.

From: Josh Poimboeuf <jpoimboe@redhat.com>
Subject: [PATCH] objtool: Detect GCC 8 cold subfunctions

GCC 8 moves a lot of unlikely code out of line to "cold" subfunctions in
.text.unlikely.  Properly detect the new subfunctions and treat them as
extensions of the original functions.

This fixes a bunch of warnings like:

  kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x33: sibling call from callable instruction with modified stack frame
  kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x290: sibling call from callable instruction with modified stack frame
  kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x25b: sibling call from callable instruction with modified stack frame
  kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x325: sibling call from callable instruction with modified stack frame

Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
 tools/objtool/check.c | 7 ++++---
 tools/objtool/elf.c   | 3 +++
 tools/objtool/elf.h   | 1 +
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 264522d4e4af..a8b3a8613b5e 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -1753,7 +1753,6 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
 	while (1) {
 		next_insn = next_insn_same_sec(file, insn);
 
-
 		if (file->c_file && func && insn->func && func != insn->func) {
 			WARN("%s() falls through to next function %s()",
 			     func->name, insn->func->name);
@@ -1869,7 +1868,9 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
 		case INSN_JUMP_UNCONDITIONAL:
 			if (insn->jump_dest &&
 			    (!func || !insn->jump_dest->func ||
-			     func == insn->jump_dest->func)) {
+			     func == insn->jump_dest->func ||
+			     insn->func->subfunc ||
+			     insn->jump_dest->func->subfunc)) {
 				ret = validate_branch(file, insn->jump_dest,
 						      state);
 				if (ret)
@@ -2064,7 +2065,7 @@ static int validate_functions(struct objtool_file *file)
 
 	for_each_sec(file, sec) {
 		list_for_each_entry(func, &sec->symbol_list, list) {
-			if (func->type != STT_FUNC)
+			if (func->type != STT_FUNC || func->subfunc)
 				continue;
 
 			insn = find_insn(file, sec, func->offset);
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index c1c338661699..0c0c7ab4a014 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -260,6 +260,9 @@ static int read_symbols(struct elf *elf)
 		sym->offset = sym->sym.st_value;
 		sym->len = sym->sym.st_size;
 
+		if (sym->type == STT_FUNC && strstr(sym->name, ".cold."))
+			sym->subfunc = true;
+
 		/* sorted insert into a per-section list */
 		entry = &sym->sec->symbol_list;
 		list_for_each_prev(tmp, &sym->sec->symbol_list) {
diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
index d86e2ff14466..dc411f9859b1 100644
--- a/tools/objtool/elf.h
+++ b/tools/objtool/elf.h
@@ -61,6 +61,7 @@ struct symbol {
 	unsigned char bind, type;
 	unsigned long offset;
 	unsigned int len;
+	bool subfunc;
 };
 
 struct rela {
-- 
2.17.0

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

* Re: Kernel build with gcc 8 a lot of warnings
  2018-05-08 13:34     ` Josh Poimboeuf
@ 2018-05-08 14:25       ` Greg KH
  2018-05-08 14:32         ` Josh Poimboeuf
  0 siblings, 1 reply; 14+ messages in thread
From: Greg KH @ 2018-05-08 14:25 UTC (permalink / raw)
  To: Josh Poimboeuf; +Cc: damian, peterz, linux-kernel

On Tue, May 08, 2018 at 08:34:47AM -0500, Josh Poimboeuf wrote:
> On Tue, May 08, 2018 at 07:51:26AM +0200, Greg KH wrote:
> > On Sun, May 06, 2018 at 11:54:53PM -0500, Josh Poimboeuf wrote:
> > > On Sat, May 05, 2018 at 09:21:12PM +0200, damian wrote:
> > > > Helllo together,
> > > > 
> > > > Hello everybody,
> > > > 
> > > > is something special to note when kernel build with gcc 8? I receive various warnings from the objtool:
> > > > With GCC 7 works all fine.
> > > > 
> > > > kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x40: sibling call from callable instruction with modified stack frame
> > > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x2a3: sibling call from callable instruction with modified stack frame
> > > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x20b: sibling call from callable instruction with modified stack frame
> > > > kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x296: sibling call from callable instruction with modified stack frame
> > > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable()+0x10: sibling call from callable instruction with modified stack frame
> > > > kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags.cold.45()+0xa: call without frame pointer save/setup
> > > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files.cold.46()+0x17: call without frame pointer save/setup
> > > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable.cold.47()+0x24: call without frame pointer save/setup
> > > > kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems.cold.48()+0x10: call without frame pointer save/setup
> > > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable.cold.49()+0x7: call without frame pointer save/setup
> > > >   CC      kernel/cgroup/stat.o
> > > >   CC [M]  arch/x86/kvm/../../../virt/kvm/kvm_main.o
> > > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic()+0x10: sibling call from callable instruction with modified stack frame
> > > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu()+0x2c: sibling call from callable instruction with modified stack frame
> > > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic.cold.6()+0x7: call without frame pointer save/setup
> > > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu.cold.7()+0x7: call without frame pointer save/setup
> > > 
> > > Thanks, this is a known issue with GCC 8 that I haven't gotten a chance
> > > to fix yet.  They're related to the fact that GCC 8 is splitting out
> > > 'unlikely' code into 'cold' subfunctions in .text.unlikely.
> > > 
> > > I've got some old patches that fix it.  Now that GCC 8 is out, I'll need
> > > get the patches dusted off and cleaned up for merging.
> > 
> > Any pointers to these patches?  Archi linux just changed their default
> > compiler to gcc 8 and now I'm seeing this in my local builds :(
> 
> I'm still dusting the code off, but this fixes most of the warnings.
> The rest of the code should hopefully be ready soon.
> 
> From: Josh Poimboeuf <jpoimboe@redhat.com>
> Subject: [PATCH] objtool: Detect GCC 8 cold subfunctions
> 
> GCC 8 moves a lot of unlikely code out of line to "cold" subfunctions in
> .text.unlikely.  Properly detect the new subfunctions and treat them as
> extensions of the original functions.
> 
> This fixes a bunch of warnings like:
> 
>   kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x33: sibling call from callable instruction with modified stack frame
>   kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x290: sibling call from callable instruction with modified stack frame
>   kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x25b: sibling call from callable instruction with modified stack frame
>   kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x325: sibling call from callable instruction with modified stack frame
> 
> Reported-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
> ---
>  tools/objtool/check.c | 7 ++++---
>  tools/objtool/elf.c   | 3 +++
>  tools/objtool/elf.h   | 1 +
>  3 files changed, 8 insertions(+), 3 deletions(-)

<snip>

Much nicer, thanks for the patch, seems to build things "quieter" now.
For the other warnings, they are "safe" to ignore, right?  It's just
objtool checking to see if all is ok, but the result should be fine no
matter what, right?

thanks,

greg k-h

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

* Re: Kernel build with gcc 8 a lot of warnings
  2018-05-08 14:25       ` Greg KH
@ 2018-05-08 14:32         ` Josh Poimboeuf
  2018-05-09  3:46           ` Josh Poimboeuf
  0 siblings, 1 reply; 14+ messages in thread
From: Josh Poimboeuf @ 2018-05-08 14:32 UTC (permalink / raw)
  To: Greg KH; +Cc: damian, peterz, linux-kernel

On Tue, May 08, 2018 at 04:25:15PM +0200, Greg KH wrote:
> On Tue, May 08, 2018 at 08:34:47AM -0500, Josh Poimboeuf wrote:
> > On Tue, May 08, 2018 at 07:51:26AM +0200, Greg KH wrote:
> > > On Sun, May 06, 2018 at 11:54:53PM -0500, Josh Poimboeuf wrote:
> > > > On Sat, May 05, 2018 at 09:21:12PM +0200, damian wrote:
> > > > > Helllo together,
> > > > > 
> > > > > Hello everybody,
> > > > > 
> > > > > is something special to note when kernel build with gcc 8? I receive various warnings from the objtool:
> > > > > With GCC 7 works all fine.
> > > > > 
> > > > > kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x40: sibling call from callable instruction with modified stack frame
> > > > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x2a3: sibling call from callable instruction with modified stack frame
> > > > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x20b: sibling call from callable instruction with modified stack frame
> > > > > kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x296: sibling call from callable instruction with modified stack frame
> > > > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable()+0x10: sibling call from callable instruction with modified stack frame
> > > > > kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags.cold.45()+0xa: call without frame pointer save/setup
> > > > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files.cold.46()+0x17: call without frame pointer save/setup
> > > > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable.cold.47()+0x24: call without frame pointer save/setup
> > > > > kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems.cold.48()+0x10: call without frame pointer save/setup
> > > > > kernel/cgroup/cgroup.o: warning: objtool: cgroup_sk_alloc_disable.cold.49()+0x7: call without frame pointer save/setup
> > > > >   CC      kernel/cgroup/stat.o
> > > > >   CC [M]  arch/x86/kvm/../../../virt/kvm/kvm_main.o
> > > > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic()+0x10: sibling call from callable instruction with modified stack frame
> > > > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu()+0x2c: sibling call from callable instruction with modified stack frame
> > > > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_register_lapic.cold.6()+0x7: call without frame pointer save/setup
> > > > > arch/x86/kernel/acpi/boot.o: warning: objtool: acpi_map_cpu.cold.7()+0x7: call without frame pointer save/setup
> > > > 
> > > > Thanks, this is a known issue with GCC 8 that I haven't gotten a chance
> > > > to fix yet.  They're related to the fact that GCC 8 is splitting out
> > > > 'unlikely' code into 'cold' subfunctions in .text.unlikely.
> > > > 
> > > > I've got some old patches that fix it.  Now that GCC 8 is out, I'll need
> > > > get the patches dusted off and cleaned up for merging.
> > > 
> > > Any pointers to these patches?  Archi linux just changed their default
> > > compiler to gcc 8 and now I'm seeing this in my local builds :(
> > 
> > I'm still dusting the code off, but this fixes most of the warnings.
> > The rest of the code should hopefully be ready soon.
> > 
> > From: Josh Poimboeuf <jpoimboe@redhat.com>
> > Subject: [PATCH] objtool: Detect GCC 8 cold subfunctions
> > 
> > GCC 8 moves a lot of unlikely code out of line to "cold" subfunctions in
> > .text.unlikely.  Properly detect the new subfunctions and treat them as
> > extensions of the original functions.
> > 
> > This fixes a bunch of warnings like:
> > 
> >   kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x33: sibling call from callable instruction with modified stack frame
> >   kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x290: sibling call from callable instruction with modified stack frame
> >   kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x25b: sibling call from callable instruction with modified stack frame
> >   kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x325: sibling call from callable instruction with modified stack frame
> > 
> > Reported-by: Arnd Bergmann <arnd@arndb.de>
> > Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
> > ---
> >  tools/objtool/check.c | 7 ++++---
> >  tools/objtool/elf.c   | 3 +++
> >  tools/objtool/elf.h   | 1 +
> >  3 files changed, 8 insertions(+), 3 deletions(-)
> 
> <snip>
> 
> Much nicer, thanks for the patch, seems to build things "quieter" now.
> For the other warnings, they are "safe" to ignore, right?  It's just
> objtool checking to see if all is ok, but the result should be fine no
> matter what, right?

Yeah, from what I can tell, there's nothing catastrophic in the rest of
the warnings.  Worst case, the ORC unwinder might get confused in a few
places.

-- 
Josh

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

* Re: Kernel build with gcc 8 a lot of warnings
  2018-05-08 14:32         ` Josh Poimboeuf
@ 2018-05-09  3:46           ` Josh Poimboeuf
  2018-05-09  7:35             ` damian
  0 siblings, 1 reply; 14+ messages in thread
From: Josh Poimboeuf @ 2018-05-09  3:46 UTC (permalink / raw)
  To: Greg KH; +Cc: damian, peterz, linux-kernel

On Tue, May 08, 2018 at 09:32:41AM -0500, Josh Poimboeuf wrote:
> On Tue, May 08, 2018 at 04:25:15PM +0200, Greg KH wrote:
> > Much nicer, thanks for the patch, seems to build things "quieter" now.
> > For the other warnings, they are "safe" to ignore, right?  It's just
> > objtool checking to see if all is ok, but the result should be fine no
> > matter what, right?
> 
> Yeah, from what I can tell, there's nothing catastrophic in the rest of
> the warnings.  Worst case, the ORC unwinder might get confused in a few
> places.

FWIW, here's the latest version of the patch.  This fixes all the
warnings on my config at least.  I'll be sending it to -tip soon if it
survives 0-day testing.

From: Josh Poimboeuf <jpoimboe@redhat.com>
Subject: [PATCH] objtool: Detect GCC 8 cold subfunctions

GCC 8 moves a lot of unlikely code out of line to "cold" subfunctions in
.text.unlikely.  Properly detect the new subfunctions and treat them as
extensions of the original functions.

This fixes a bunch of warnings like:

  kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x33: sibling call from callable instruction with modified stack frame
  kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x290: sibling call from callable instruction with modified stack frame
  kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x25b: sibling call from callable instruction with modified stack frame
  kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x325: sibling call from callable instruction with modified stack frame

Reported-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
---
 tools/objtool/check.c | 104 +++++++++++++++++++++++++-----------------
 tools/objtool/elf.c   |  42 ++++++++++++++++-
 tools/objtool/elf.h   |   2 +
 3 files changed, 104 insertions(+), 44 deletions(-)

diff --git a/tools/objtool/check.c b/tools/objtool/check.c
index 264522d4e4af..ee72958d3464 100644
--- a/tools/objtool/check.c
+++ b/tools/objtool/check.c
@@ -59,6 +59,31 @@ static struct instruction *next_insn_same_sec(struct objtool_file *file,
 	return next;
 }
 
+static struct instruction *next_insn_same_func(struct objtool_file *file,
+					       struct instruction *insn)
+{
+	struct instruction *next = list_next_entry(insn, list);
+	struct symbol *func = insn->func;
+
+	if (!func)
+		return NULL;
+
+	if (&next->list != &file->insn_list && next->func == func)
+		return next;
+
+	/* Check if we're already in the subfunction: */
+	if (func == func->cfunc)
+		return NULL;
+
+	/* Move to the subfunction: */
+	return find_insn(file, func->cfunc->sec, func->cfunc->offset);
+}
+
+#define func_for_each_insn_all(file, func, insn)			\
+	for (insn = find_insn(file, func->sec, func->offset);		\
+	     insn;							\
+	     insn = next_insn_same_func(file, insn))
+
 #define func_for_each_insn(file, func, insn)				\
 	for (insn = find_insn(file, func->sec, func->offset);		\
 	     insn && &insn->list != &file->insn_list &&			\
@@ -149,10 +174,14 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
 			if (!strcmp(func->name, global_noreturns[i]))
 				return 1;
 
-	if (!func->sec)
+	if (!func->len)
 		return 0;
 
-	func_for_each_insn(file, func, insn) {
+	insn = find_insn(file, func->sec, func->offset);
+	if (!insn->func)
+		return 0;
+
+	func_for_each_insn_all(file, func, insn) {
 		empty = false;
 
 		if (insn->type == INSN_RETURN)
@@ -167,28 +196,17 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
 	 * case, the function's dead-end status depends on whether the target
 	 * of the sibling call returns.
 	 */
-	func_for_each_insn(file, func, insn) {
-		if (insn->sec != func->sec ||
-		    insn->offset >= func->offset + func->len)
-			break;
-
+	func_for_each_insn_all(file, func, insn) {
 		if (insn->type == INSN_JUMP_UNCONDITIONAL) {
 			struct instruction *dest = insn->jump_dest;
-			struct symbol *dest_func;
 
 			if (!dest)
 				/* sibling call to another file */
 				return 0;
 
-			if (dest->sec != func->sec ||
-			    dest->offset < func->offset ||
-			    dest->offset >= func->offset + func->len) {
-				/* local sibling call */
-				dest_func = find_symbol_by_offset(dest->sec,
-								  dest->offset);
-				if (!dest_func)
-					continue;
+			if (dest->func && dest->func->pfunc != insn->func->pfunc) {
 
+				/* local sibling call */
 				if (recursion == 5) {
 					/*
 					 * Infinite recursion: two functions
@@ -199,7 +217,7 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
 					return 0;
 				}
 
-				return __dead_end_function(file, dest_func,
+				return __dead_end_function(file, dest->func,
 							   recursion + 1);
 			}
 		}
@@ -426,7 +444,7 @@ static void add_ignores(struct objtool_file *file)
 			if (!ignore_func(file, func))
 				continue;
 
-			func_for_each_insn(file, func, insn)
+			func_for_each_insn_all(file, func, insn)
 				insn->ignore = true;
 		}
 	}
@@ -786,30 +804,28 @@ static int add_special_section_alts(struct objtool_file *file)
 	return ret;
 }
 
-static int add_switch_table(struct objtool_file *file, struct symbol *func,
-			    struct instruction *insn, struct rela *table,
-			    struct rela *next_table)
+static int add_switch_table(struct objtool_file *file, struct instruction *insn,
+			    struct rela *table, struct rela *next_table)
 {
 	struct rela *rela = table;
 	struct instruction *alt_insn;
 	struct alternative *alt;
+	struct symbol *pfunc = insn->func->pfunc;
+	unsigned int prev_offset = 0;
 
 	list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) {
 		if (rela == next_table)
 			break;
 
-		if (rela->sym->sec != insn->sec ||
-		    rela->addend <= func->offset ||
-		    rela->addend >= func->offset + func->len)
+		if (prev_offset && rela->offset != prev_offset + sizeof(long))
 			break;
 
-		alt_insn = find_insn(file, insn->sec, rela->addend);
-		if (!alt_insn) {
-			WARN("%s: can't find instruction at %s+0x%x",
-			     file->rodata->rela->name, insn->sec->name,
-			     rela->addend);
-			return -1;
-		}
+		alt_insn = find_insn(file, rela->sym->sec, rela->addend);
+		if (!alt_insn)
+			break;
+
+		if (alt_insn->func->pfunc != pfunc)
+			break;
 
 		alt = malloc(sizeof(*alt));
 		if (!alt) {
@@ -819,6 +835,13 @@ static int add_switch_table(struct objtool_file *file, struct symbol *func,
 
 		alt->insn = alt_insn;
 		list_add_tail(&alt->list, &insn->alts);
+		prev_offset = rela->offset;
+	}
+
+	if (!prev_offset) {
+		WARN_FUNC("can't find switch jump table",
+			  insn->sec, insn->offset);
+		return -1;
 	}
 
 	return 0;
@@ -947,7 +970,7 @@ static int add_func_switch_tables(struct objtool_file *file,
 	struct rela *rela, *prev_rela = NULL;
 	int ret;
 
-	func_for_each_insn(file, func, insn) {
+	func_for_each_insn_all(file, func, insn) {
 		if (!last)
 			last = insn;
 
@@ -978,8 +1001,7 @@ static int add_func_switch_tables(struct objtool_file *file,
 		 * the beginning of another switch table in the same function.
 		 */
 		if (prev_jump) {
-			ret = add_switch_table(file, func, prev_jump, prev_rela,
-					       rela);
+			ret = add_switch_table(file, prev_jump, prev_rela, rela);
 			if (ret)
 				return ret;
 		}
@@ -989,7 +1011,7 @@ static int add_func_switch_tables(struct objtool_file *file,
 	}
 
 	if (prev_jump) {
-		ret = add_switch_table(file, func, prev_jump, prev_rela, NULL);
+		ret = add_switch_table(file, prev_jump, prev_rela, NULL);
 		if (ret)
 			return ret;
 	}
@@ -1753,15 +1775,13 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
 	while (1) {
 		next_insn = next_insn_same_sec(file, insn);
 
-
-		if (file->c_file && func && insn->func && func != insn->func) {
+		if (file->c_file && func && insn->func && func != insn->func->pfunc) {
 			WARN("%s() falls through to next function %s()",
 			     func->name, insn->func->name);
 			return 1;
 		}
 
-		if (insn->func)
-			func = insn->func;
+		func = insn->func ? insn->func->pfunc : NULL;
 
 		if (func && insn->ignore) {
 			WARN_FUNC("BUG: why am I validating an ignored function?",
@@ -1782,7 +1802,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
 
 				i = insn;
 				save_insn = NULL;
-				func_for_each_insn_continue_reverse(file, func, i) {
+				func_for_each_insn_continue_reverse(file, insn->func, i) {
 					if (i->save) {
 						save_insn = i;
 						break;
@@ -1869,7 +1889,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
 		case INSN_JUMP_UNCONDITIONAL:
 			if (insn->jump_dest &&
 			    (!func || !insn->jump_dest->func ||
-			     func == insn->jump_dest->func)) {
+			     insn->jump_dest->func->pfunc == func)) {
 				ret = validate_branch(file, insn->jump_dest,
 						      state);
 				if (ret)
@@ -2064,7 +2084,7 @@ static int validate_functions(struct objtool_file *file)
 
 	for_each_sec(file, sec) {
 		list_for_each_entry(func, &sec->symbol_list, list) {
-			if (func->type != STT_FUNC)
+			if (func->type != STT_FUNC || func->pfunc != func)
 				continue;
 
 			insn = find_insn(file, sec, func->offset);
diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
index c1c338661699..4e60e105583e 100644
--- a/tools/objtool/elf.c
+++ b/tools/objtool/elf.c
@@ -79,6 +79,19 @@ struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset)
 	return NULL;
 }
 
+struct symbol *find_symbol_by_name(struct elf *elf, const char *name)
+{
+	struct section *sec;
+	struct symbol *sym;
+
+	list_for_each_entry(sec, &elf->sections, list)
+		list_for_each_entry(sym, &sec->symbol_list, list)
+			if (!strcmp(sym->name, name))
+				return sym;
+
+	return NULL;
+}
+
 struct symbol *find_symbol_containing(struct section *sec, unsigned long offset)
 {
 	struct symbol *sym;
@@ -203,10 +216,11 @@ static int read_sections(struct elf *elf)
 
 static int read_symbols(struct elf *elf)
 {
-	struct section *symtab;
-	struct symbol *sym;
+	struct section *symtab, *sec;
+	struct symbol *sym, *pfunc;
 	struct list_head *entry, *tmp;
 	int symbols_nr, i;
+	char *coldstr;
 
 	symtab = find_section_by_name(elf, ".symtab");
 	if (!symtab) {
@@ -281,6 +295,30 @@ static int read_symbols(struct elf *elf)
 		hash_add(sym->sec->symbol_hash, &sym->hash, sym->idx);
 	}
 
+	/* 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) {
+			if (sym->type != STT_FUNC)
+				continue;
+			sym->pfunc = sym->cfunc = sym;
+			coldstr = strstr(sym->name, ".cold.");
+			if (coldstr) {
+				coldstr[0] = '\0';
+				pfunc = find_symbol_by_name(elf, sym->name);
+				coldstr[0] = '.';
+
+				if (!pfunc) {
+					WARN("%s(): can't find parent function",
+					     sym->name);
+					goto err;
+				}
+
+				sym->pfunc = pfunc;
+				pfunc->cfunc = sym;
+			}
+		}
+	}
+
 	return 0;
 
 err:
diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
index d86e2ff14466..de5cd2ddded9 100644
--- a/tools/objtool/elf.h
+++ b/tools/objtool/elf.h
@@ -61,6 +61,7 @@ struct symbol {
 	unsigned char bind, type;
 	unsigned long offset;
 	unsigned int len;
+	struct symbol *pfunc, *cfunc;
 };
 
 struct rela {
@@ -86,6 +87,7 @@ struct elf {
 struct elf *elf_open(const char *name, int flags);
 struct section *find_section_by_name(struct elf *elf, const char *name);
 struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
+struct symbol *find_symbol_by_name(struct elf *elf, const char *name);
 struct symbol *find_symbol_containing(struct section *sec, unsigned long offset);
 struct rela *find_rela_by_dest(struct section *sec, unsigned long offset);
 struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset,
-- 
2.17.0

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

* Re: Kernel build with gcc 8 a lot of warnings
  2018-05-09  3:46           ` Josh Poimboeuf
@ 2018-05-09  7:35             ` damian
  2018-05-09 15:23               ` Josh Poimboeuf
  0 siblings, 1 reply; 14+ messages in thread
From: damian @ 2018-05-09  7:35 UTC (permalink / raw)
  To: Josh Poimboeuf; +Cc: Greg KH, damian, peterz, linux-kernel

Hi Josh,

i tested the patch on my maschine it works fine. 

Best regards
Damian

On Tue, 08. May 22:46, Josh Poimboeuf wrote:
> On Tue, May 08, 2018 at 09:32:41AM -0500, Josh Poimboeuf wrote:
> > On Tue, May 08, 2018 at 04:25:15PM +0200, Greg KH wrote:
> > > Much nicer, thanks for the patch, seems to build things "quieter" now.
> > > For the other warnings, they are "safe" to ignore, right?  It's just
> > > objtool checking to see if all is ok, but the result should be fine no
> > > matter what, right?
> > 
> > Yeah, from what I can tell, there's nothing catastrophic in the rest of
> > the warnings.  Worst case, the ORC unwinder might get confused in a few
> > places.
> 
> FWIW, here's the latest version of the patch.  This fixes all the
> warnings on my config at least.  I'll be sending it to -tip soon if it
> survives 0-day testing.
> 
> From: Josh Poimboeuf <jpoimboe@redhat.com>
> Subject: [PATCH] objtool: Detect GCC 8 cold subfunctions
> 
> GCC 8 moves a lot of unlikely code out of line to "cold" subfunctions in
> .text.unlikely.  Properly detect the new subfunctions and treat them as
> extensions of the original functions.
> 
> This fixes a bunch of warnings like:
> 
>   kernel/cgroup/cgroup.o: warning: objtool: parse_cgroup_root_flags()+0x33: sibling call from callable instruction with modified stack frame
>   kernel/cgroup/cgroup.o: warning: objtool: cgroup_addrm_files()+0x290: sibling call from callable instruction with modified stack frame
>   kernel/cgroup/cgroup.o: warning: objtool: cgroup_apply_control_enable()+0x25b: sibling call from callable instruction with modified stack frame
>   kernel/cgroup/cgroup.o: warning: objtool: rebind_subsystems()+0x325: sibling call from callable instruction with modified stack frame
> 
> Reported-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
> ---
>  tools/objtool/check.c | 104 +++++++++++++++++++++++++-----------------
>  tools/objtool/elf.c   |  42 ++++++++++++++++-
>  tools/objtool/elf.h   |   2 +
>  3 files changed, 104 insertions(+), 44 deletions(-)
> 
> diff --git a/tools/objtool/check.c b/tools/objtool/check.c
> index 264522d4e4af..ee72958d3464 100644
> --- a/tools/objtool/check.c
> +++ b/tools/objtool/check.c
> @@ -59,6 +59,31 @@ static struct instruction *next_insn_same_sec(struct objtool_file *file,
>  	return next;
>  }
>  
> +static struct instruction *next_insn_same_func(struct objtool_file *file,
> +					       struct instruction *insn)
> +{
> +	struct instruction *next = list_next_entry(insn, list);
> +	struct symbol *func = insn->func;
> +
> +	if (!func)
> +		return NULL;
> +
> +	if (&next->list != &file->insn_list && next->func == func)
> +		return next;
> +
> +	/* Check if we're already in the subfunction: */
> +	if (func == func->cfunc)
> +		return NULL;
> +
> +	/* Move to the subfunction: */
> +	return find_insn(file, func->cfunc->sec, func->cfunc->offset);
> +}
> +
> +#define func_for_each_insn_all(file, func, insn)			\
> +	for (insn = find_insn(file, func->sec, func->offset);		\
> +	     insn;							\
> +	     insn = next_insn_same_func(file, insn))
> +
>  #define func_for_each_insn(file, func, insn)				\
>  	for (insn = find_insn(file, func->sec, func->offset);		\
>  	     insn && &insn->list != &file->insn_list &&			\
> @@ -149,10 +174,14 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
>  			if (!strcmp(func->name, global_noreturns[i]))
>  				return 1;
>  
> -	if (!func->sec)
> +	if (!func->len)
>  		return 0;
>  
> -	func_for_each_insn(file, func, insn) {
> +	insn = find_insn(file, func->sec, func->offset);
> +	if (!insn->func)
> +		return 0;
> +
> +	func_for_each_insn_all(file, func, insn) {
>  		empty = false;
>  
>  		if (insn->type == INSN_RETURN)
> @@ -167,28 +196,17 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
>  	 * case, the function's dead-end status depends on whether the target
>  	 * of the sibling call returns.
>  	 */
> -	func_for_each_insn(file, func, insn) {
> -		if (insn->sec != func->sec ||
> -		    insn->offset >= func->offset + func->len)
> -			break;
> -
> +	func_for_each_insn_all(file, func, insn) {
>  		if (insn->type == INSN_JUMP_UNCONDITIONAL) {
>  			struct instruction *dest = insn->jump_dest;
> -			struct symbol *dest_func;
>  
>  			if (!dest)
>  				/* sibling call to another file */
>  				return 0;
>  
> -			if (dest->sec != func->sec ||
> -			    dest->offset < func->offset ||
> -			    dest->offset >= func->offset + func->len) {
> -				/* local sibling call */
> -				dest_func = find_symbol_by_offset(dest->sec,
> -								  dest->offset);
> -				if (!dest_func)
> -					continue;
> +			if (dest->func && dest->func->pfunc != insn->func->pfunc) {
>  
> +				/* local sibling call */
>  				if (recursion == 5) {
>  					/*
>  					 * Infinite recursion: two functions
> @@ -199,7 +217,7 @@ static int __dead_end_function(struct objtool_file *file, struct symbol *func,
>  					return 0;
>  				}
>  
> -				return __dead_end_function(file, dest_func,
> +				return __dead_end_function(file, dest->func,
>  							   recursion + 1);
>  			}
>  		}
> @@ -426,7 +444,7 @@ static void add_ignores(struct objtool_file *file)
>  			if (!ignore_func(file, func))
>  				continue;
>  
> -			func_for_each_insn(file, func, insn)
> +			func_for_each_insn_all(file, func, insn)
>  				insn->ignore = true;
>  		}
>  	}
> @@ -786,30 +804,28 @@ static int add_special_section_alts(struct objtool_file *file)
>  	return ret;
>  }
>  
> -static int add_switch_table(struct objtool_file *file, struct symbol *func,
> -			    struct instruction *insn, struct rela *table,
> -			    struct rela *next_table)
> +static int add_switch_table(struct objtool_file *file, struct instruction *insn,
> +			    struct rela *table, struct rela *next_table)
>  {
>  	struct rela *rela = table;
>  	struct instruction *alt_insn;
>  	struct alternative *alt;
> +	struct symbol *pfunc = insn->func->pfunc;
> +	unsigned int prev_offset = 0;
>  
>  	list_for_each_entry_from(rela, &file->rodata->rela->rela_list, list) {
>  		if (rela == next_table)
>  			break;
>  
> -		if (rela->sym->sec != insn->sec ||
> -		    rela->addend <= func->offset ||
> -		    rela->addend >= func->offset + func->len)
> +		if (prev_offset && rela->offset != prev_offset + sizeof(long))
>  			break;
>  
> -		alt_insn = find_insn(file, insn->sec, rela->addend);
> -		if (!alt_insn) {
> -			WARN("%s: can't find instruction at %s+0x%x",
> -			     file->rodata->rela->name, insn->sec->name,
> -			     rela->addend);
> -			return -1;
> -		}
> +		alt_insn = find_insn(file, rela->sym->sec, rela->addend);
> +		if (!alt_insn)
> +			break;
> +
> +		if (alt_insn->func->pfunc != pfunc)
> +			break;
>  
>  		alt = malloc(sizeof(*alt));
>  		if (!alt) {
> @@ -819,6 +835,13 @@ static int add_switch_table(struct objtool_file *file, struct symbol *func,
>  
>  		alt->insn = alt_insn;
>  		list_add_tail(&alt->list, &insn->alts);
> +		prev_offset = rela->offset;
> +	}
> +
> +	if (!prev_offset) {
> +		WARN_FUNC("can't find switch jump table",
> +			  insn->sec, insn->offset);
> +		return -1;
>  	}
>  
>  	return 0;
> @@ -947,7 +970,7 @@ static int add_func_switch_tables(struct objtool_file *file,
>  	struct rela *rela, *prev_rela = NULL;
>  	int ret;
>  
> -	func_for_each_insn(file, func, insn) {
> +	func_for_each_insn_all(file, func, insn) {
>  		if (!last)
>  			last = insn;
>  
> @@ -978,8 +1001,7 @@ static int add_func_switch_tables(struct objtool_file *file,
>  		 * the beginning of another switch table in the same function.
>  		 */
>  		if (prev_jump) {
> -			ret = add_switch_table(file, func, prev_jump, prev_rela,
> -					       rela);
> +			ret = add_switch_table(file, prev_jump, prev_rela, rela);
>  			if (ret)
>  				return ret;
>  		}
> @@ -989,7 +1011,7 @@ static int add_func_switch_tables(struct objtool_file *file,
>  	}
>  
>  	if (prev_jump) {
> -		ret = add_switch_table(file, func, prev_jump, prev_rela, NULL);
> +		ret = add_switch_table(file, prev_jump, prev_rela, NULL);
>  		if (ret)
>  			return ret;
>  	}
> @@ -1753,15 +1775,13 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
>  	while (1) {
>  		next_insn = next_insn_same_sec(file, insn);
>  
> -
> -		if (file->c_file && func && insn->func && func != insn->func) {
> +		if (file->c_file && func && insn->func && func != insn->func->pfunc) {
>  			WARN("%s() falls through to next function %s()",
>  			     func->name, insn->func->name);
>  			return 1;
>  		}
>  
> -		if (insn->func)
> -			func = insn->func;
> +		func = insn->func ? insn->func->pfunc : NULL;
>  
>  		if (func && insn->ignore) {
>  			WARN_FUNC("BUG: why am I validating an ignored function?",
> @@ -1782,7 +1802,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
>  
>  				i = insn;
>  				save_insn = NULL;
> -				func_for_each_insn_continue_reverse(file, func, i) {
> +				func_for_each_insn_continue_reverse(file, insn->func, i) {
>  					if (i->save) {
>  						save_insn = i;
>  						break;
> @@ -1869,7 +1889,7 @@ static int validate_branch(struct objtool_file *file, struct instruction *first,
>  		case INSN_JUMP_UNCONDITIONAL:
>  			if (insn->jump_dest &&
>  			    (!func || !insn->jump_dest->func ||
> -			     func == insn->jump_dest->func)) {
> +			     insn->jump_dest->func->pfunc == func)) {
>  				ret = validate_branch(file, insn->jump_dest,
>  						      state);
>  				if (ret)
> @@ -2064,7 +2084,7 @@ static int validate_functions(struct objtool_file *file)
>  
>  	for_each_sec(file, sec) {
>  		list_for_each_entry(func, &sec->symbol_list, list) {
> -			if (func->type != STT_FUNC)
> +			if (func->type != STT_FUNC || func->pfunc != func)
>  				continue;
>  
>  			insn = find_insn(file, sec, func->offset);
> diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c
> index c1c338661699..4e60e105583e 100644
> --- a/tools/objtool/elf.c
> +++ b/tools/objtool/elf.c
> @@ -79,6 +79,19 @@ struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset)
>  	return NULL;
>  }
>  
> +struct symbol *find_symbol_by_name(struct elf *elf, const char *name)
> +{
> +	struct section *sec;
> +	struct symbol *sym;
> +
> +	list_for_each_entry(sec, &elf->sections, list)
> +		list_for_each_entry(sym, &sec->symbol_list, list)
> +			if (!strcmp(sym->name, name))
> +				return sym;
> +
> +	return NULL;
> +}
> +
>  struct symbol *find_symbol_containing(struct section *sec, unsigned long offset)
>  {
>  	struct symbol *sym;
> @@ -203,10 +216,11 @@ static int read_sections(struct elf *elf)
>  
>  static int read_symbols(struct elf *elf)
>  {
> -	struct section *symtab;
> -	struct symbol *sym;
> +	struct section *symtab, *sec;
> +	struct symbol *sym, *pfunc;
>  	struct list_head *entry, *tmp;
>  	int symbols_nr, i;
> +	char *coldstr;
>  
>  	symtab = find_section_by_name(elf, ".symtab");
>  	if (!symtab) {
> @@ -281,6 +295,30 @@ static int read_symbols(struct elf *elf)
>  		hash_add(sym->sec->symbol_hash, &sym->hash, sym->idx);
>  	}
>  
> +	/* 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) {
> +			if (sym->type != STT_FUNC)
> +				continue;
> +			sym->pfunc = sym->cfunc = sym;
> +			coldstr = strstr(sym->name, ".cold.");
> +			if (coldstr) {
> +				coldstr[0] = '\0';
> +				pfunc = find_symbol_by_name(elf, sym->name);
> +				coldstr[0] = '.';
> +
> +				if (!pfunc) {
> +					WARN("%s(): can't find parent function",
> +					     sym->name);
> +					goto err;
> +				}
> +
> +				sym->pfunc = pfunc;
> +				pfunc->cfunc = sym;
> +			}
> +		}
> +	}
> +
>  	return 0;
>  
>  err:
> diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
> index d86e2ff14466..de5cd2ddded9 100644
> --- a/tools/objtool/elf.h
> +++ b/tools/objtool/elf.h
> @@ -61,6 +61,7 @@ struct symbol {
>  	unsigned char bind, type;
>  	unsigned long offset;
>  	unsigned int len;
> +	struct symbol *pfunc, *cfunc;
>  };
>  
>  struct rela {
> @@ -86,6 +87,7 @@ struct elf {
>  struct elf *elf_open(const char *name, int flags);
>  struct section *find_section_by_name(struct elf *elf, const char *name);
>  struct symbol *find_symbol_by_offset(struct section *sec, unsigned long offset);
> +struct symbol *find_symbol_by_name(struct elf *elf, const char *name);
>  struct symbol *find_symbol_containing(struct section *sec, unsigned long offset);
>  struct rela *find_rela_by_dest(struct section *sec, unsigned long offset);
>  struct rela *find_rela_by_dest_range(struct section *sec, unsigned long offset,
> -- 
> 2.17.0
> 

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

* RE: Kernel build with gcc 8 a lot of warnings
  2018-05-05 19:21 Kernel build with gcc 8 a lot of warnings damian
  2018-05-07  4:54 ` Josh Poimboeuf
@ 2018-05-09 14:27 ` David Laight
  2018-05-09 14:54   ` Josh Poimboeuf
  1 sibling, 1 reply; 14+ messages in thread
From: David Laight @ 2018-05-09 14:27 UTC (permalink / raw)
  To: 'damian', jpoimboe, peterz; +Cc: linux-kernel

From: damian
> Sent: 05 May 2018 20:21
> is something special to note when kernel build with gcc 8? I receive various warnings from the
> objtool:

Someone ought to persuade the gcc folks to try compiling the Linux kernel
before releasing a new compiler :-)

	David

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

* Re: Kernel build with gcc 8 a lot of warnings
  2018-05-09 14:27 ` David Laight
@ 2018-05-09 14:54   ` Josh Poimboeuf
  0 siblings, 0 replies; 14+ messages in thread
From: Josh Poimboeuf @ 2018-05-09 14:54 UTC (permalink / raw)
  To: David Laight; +Cc: 'damian', peterz, linux-kernel

On Wed, May 09, 2018 at 02:27:48PM +0000, David Laight wrote:
> From: damian
> > Sent: 05 May 2018 20:21
> > is something special to note when kernel build with gcc 8? I receive various warnings from the
> > objtool:
> 
> Someone ought to persuade the gcc folks to try compiling the Linux kernel
> before releasing a new compiler :-)

That would have been good.  Though, I also deserve blame as Arnd warned
me about this several months ago before the spec-pocalypse diverted my
attention.

-- 
Josh

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

* Re: Kernel build with gcc 8 a lot of warnings
  2018-05-09  7:35             ` damian
@ 2018-05-09 15:23               ` Josh Poimboeuf
  2018-05-09 19:15                 ` damian
  0 siblings, 1 reply; 14+ messages in thread
From: Josh Poimboeuf @ 2018-05-09 15:23 UTC (permalink / raw)
  To: damian; +Cc: Greg KH, damian, peterz, linux-kernel, Arnd Bergmann

On Wed, May 09, 2018 at 09:35:04AM +0200, damian wrote:
> Hi Josh,
> 
> i tested the patch on my maschine it works fine. 
> 
> Best regards
> Damian

Thanks.  0-day found a few more issues.  The latest patches are at:

  git://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux objtool-gcc8

Waiting for 0-day to run them again, then I'll be submitting them
shortly after.

-- 
Josh

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

* Re: Kernel build with gcc 8 a lot of warnings
  2018-05-09 15:23               ` Josh Poimboeuf
@ 2018-05-09 19:15                 ` damian
  0 siblings, 0 replies; 14+ messages in thread
From: damian @ 2018-05-09 19:15 UTC (permalink / raw)
  To: Josh Poimboeuf; +Cc: Greg KH, peterz, linux-kernel, Arnd Bergmann

On Wed, 09. May 10:23, Josh Poimboeuf wrote:
> On Wed, May 09, 2018 at 09:35:04AM +0200, damian wrote:
> > Hi Josh,
> > 
> > i tested the patch on my maschine it works fine. 
> > 
> > Best regards
> > Damian
> 
> Thanks.  0-day found a few more issues.  The latest patches are at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/jpoimboe/linux objtool-gcc8
> 
> Waiting for 0-day to run them again, then I'll be submitting them
> shortly after.
> 
> -- 
> Josh

Hi Josh,

my test was successfull.

regards
Damian
 

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

end of thread, other threads:[~2018-05-09 19:15 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-05 19:21 Kernel build with gcc 8 a lot of warnings damian
2018-05-07  4:54 ` Josh Poimboeuf
2018-05-07 10:57   ` damian
2018-05-08  5:51   ` Greg KH
2018-05-08  5:58     ` Greg KH
2018-05-08 13:34     ` Josh Poimboeuf
2018-05-08 14:25       ` Greg KH
2018-05-08 14:32         ` Josh Poimboeuf
2018-05-09  3:46           ` Josh Poimboeuf
2018-05-09  7:35             ` damian
2018-05-09 15:23               ` Josh Poimboeuf
2018-05-09 19:15                 ` damian
2018-05-09 14:27 ` David Laight
2018-05-09 14:54   ` Josh Poimboeuf

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.