All of lore.kernel.org
 help / color / mirror / Atom feed
From: damian <linux_dti@icloud.com>
To: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Greg KH <gregkh@linuxfoundation.org>,
	damian <damian.tometzki@icloud.com>,
	peterz@infradead.org, linux-kernel@vger.kernel.org
Subject: Re: Kernel build with gcc 8 a lot of warnings
Date: Wed, 09 May 2018 09:35:04 +0200	[thread overview]
Message-ID: <20180509073503.GA2116@zrhn9910b> (raw)
In-Reply-To: <20180509034646.7qftdvummkz7b2pi@treble>

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
> 

  reply	other threads:[~2018-05-09  7:35 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180509073503.GA2116@zrhn9910b \
    --to=linux_dti@icloud.com \
    --cc=damian.tometzki@icloud.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jpoimboe@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peterz@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.