Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 58fb0d4f authored by Sam Ravnborg's avatar Sam Ravnborg
Browse files

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: default avatarSam Ravnborg <sam@ravnborg.org>
parent ff13f926
Loading
Loading
Loading
Loading
+52 −52
Original line number Diff line number Diff line
@@ -607,7 +607,10 @@ static int strrcmp(const char *s, const char *sub)

static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
{
	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 @@ static int section_mismatch(const char *fromsec, const char *tosec)
	return 0;
}


/**
 * Whitelist to allow certain references to pass with no warning.
 *
@@ -856,36 +858,35 @@ static int section_mismatch(const char *fromsec, const char *tosec)
 *   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 1;
}

/**
@@ -987,41 +988,49 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
	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 @@ static void section_rela(const char *modname, struct elf_info *elf,
	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 @@ static void section_rela(const char *modname, struct elf_info *elf,
	/* 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 @@ static void section_rela(const char *modname, struct elf_info *elf,
		/* 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 @@ static void section_rel(const char *modname, struct elf_info *elf,
	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 @@ static void section_rel(const char *modname, struct elf_info *elf,
		/* 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);
	}
}