kbuild: simplified warning report in modpost

Refactor code so the warning report function
does nothing else than reporting warnings.
As a side effect some other code paths were cleaned
up by this.

Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index e4099cd..0a80aca 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -607,7 +607,10 @@
 
 static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
 {
-	return elf->strtab + sym->st_name;
+	if (sym)
+		return elf->strtab + sym->st_name;
+	else
+		return "";
 }
 
 static const char *sec_name(struct elf_info *elf, int shndx)
@@ -812,7 +815,6 @@
 	return 0;
 }
 
-
 /**
  * Whitelist to allow certain references to pass with no warning.
  *
@@ -856,36 +858,35 @@
  *   refsymname = __init_begin, _sinittext, _einittext
  *
  **/
-static int secref_whitelist(const char *modname, const char *tosec,
-			    const char *fromsec, const char *atsym,
-			    const char *refsymname)
+static int secref_whitelist(const char *fromsec, const char *fromsym,
+			    const char *tosec, const char *tosym)
 {
 	/* Check for pattern 0 */
 	if (match(fromsec, initref_sections))
-		return 1;
+		return 0;
 
 	/* Check for pattern 1 */
 	if (match(tosec, init_data_sections) &&
 	    match(fromsec, data_sections) &&
-	    (strncmp(atsym, "__param", strlen("__param")) == 0))
-		return 1;
+	    (strncmp(fromsym, "__param", strlen("__param")) == 0))
+		return 0;
 
 	/* Check for pattern 2 */
 	if (match(tosec, init_exit_sections) &&
 	    match(fromsec, data_sections) &&
-	    match(atsym, symbol_white_list))
-		return 1;
+	    match(fromsym, symbol_white_list))
+		return 0;
 
 	/* Check for pattern 3 */
 	if (match(fromsec, head_sections) &&
 	    match(tosec, init_sections))
-	return 1;
+		return 0;
 
 	/* Check for pattern 4 */
-	if (match(refsymname, linker_symbols))
-		return 1;
+	if (match(tosym, linker_symbols))
+		return 0;
 
-	return 0;
+	return 1;
 }
 
 /**
@@ -987,41 +988,49 @@
 	return near;
 }
 
-/**
+/*
  * Print a warning about a section mismatch.
  * Try to find symbols near it so user can find it.
  * Check whitelist before warning - it may be a false positive.
- **/
-static void warn_sec_mismatch(const char *modname, const char *fromsec,
-			      struct elf_info *elf, Elf_Sym *sym, Elf_Rela r)
+ */
+static void report_sec_mismatch(const char *modname,
+                                const char *fromsec,
+                                unsigned long long fromaddr,
+                                const char *fromsym,
+                                const char *tosec, const char *tosym)
 {
-	Elf_Sym *where;
-	Elf_Sym *refsym;
-	const char *refsymname = "";
-	const char *secname;
-
-	secname = sec_name(elf, sym->st_shndx);
-	where = find_elf_symbol2(elf, r.r_offset, fromsec);
-
-	refsym = find_elf_symbol(elf, r.r_addend, sym);
-	if (refsym && strlen(sym_name(elf, refsym)))
-		refsymname = sym_name(elf, refsym);
-
-	/* check whitelist - we may ignore it */
-	if (secref_whitelist(modname, secname, fromsec,
-			     where ? sym_name(elf, where) : "",
-	                     refsymname))
-		return;
-
-	if (where) {
+	if (strlen(tosym)) {
 		warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
 		     "in '%s'\n",
-		     modname, fromsec, (unsigned long long)r.r_offset,
-		     secname, refsymname, sym_name(elf, where));
+		     modname, fromsec, fromaddr,
+		     tosec, tosym, fromsym);
 	} else {
 		warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n",
-		     modname, fromsec, (unsigned long long)r.r_offset,
-		     secname, refsymname);
+		     modname, fromsec, fromaddr,
+		     tosec, tosym);
+	}
+}
+
+static void check_section_mismatch(const char *modname, struct elf_info *elf,
+                                   Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
+{
+	const char *tosec;
+
+	tosec = sec_name(elf, sym->st_shndx);
+	if (section_mismatch(fromsec, tosec)) {
+		const char *fromsym;
+		const char *tosym;
+
+		fromsym = sym_name(elf,
+		          find_elf_symbol2(elf, r->r_offset, fromsec));
+		tosym = sym_name(elf,
+		        find_elf_symbol(elf, r->r_addend, sym));
+
+		/* check whitelist - we may ignore it */
+		if (secref_whitelist(fromsec, fromsym, tosec, tosym)) {
+			report_sec_mismatch(modname, fromsec, r->r_offset,
+			                    fromsym, tosec, tosym);
+		}
 	}
 }
 
@@ -1107,7 +1116,6 @@
 	Elf_Rela r;
 	unsigned int r_sym;
 	const char *fromsec;
-	const char * tosec;
 
 	Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
 	Elf_Rela *stop  = (void *)start + sechdr->sh_size;
@@ -1117,7 +1125,6 @@
 	/* if from section (name) is know good then skip it */
 	if (match(fromsec, section_white_list))
 		return;
-
 	for (rela = start; rela < stop; rela++) {
 		r.r_offset = TO_NATIVE(rela->r_offset);
 #if KERNEL_ELFCLASS == ELFCLASS64
@@ -1140,10 +1147,7 @@
 		/* Skip special sections */
 		if (sym->st_shndx >= SHN_LORESERVE)
 			continue;
-
-		tosec = sec_name(elf, sym->st_shndx);
-		if (section_mismatch(fromsec, tosec))
-			warn_sec_mismatch(modname, fromsec, elf, sym, r);
+		check_section_mismatch(modname, elf, &r, sym, fromsec);
 	}
 }
 
@@ -1155,7 +1159,6 @@
 	Elf_Rela r;
 	unsigned int r_sym;
 	const char *fromsec;
-	const char * tosec;
 
 	Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
 	Elf_Rel *stop  = (void *)start + sechdr->sh_size;
@@ -1202,10 +1205,7 @@
 		/* Skip special sections */
 		if (sym->st_shndx >= SHN_LORESERVE)
 			continue;
-
-		tosec = sec_name(elf, sym->st_shndx);
-		if (section_mismatch(fromsec, tosec))
-			warn_sec_mismatch(modname, fromsec, elf, sym, r);
+		check_section_mismatch(modname, elf, &r, sym, fromsec);
 	}
 }