提交 58fb0d4f 编写于 作者: S Sam Ravnborg

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: NSam Ravnborg <sam@ravnborg.org>
上级 ff13f926
...@@ -607,7 +607,10 @@ static int strrcmp(const char *s, const char *sub) ...@@ -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) 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) 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) ...@@ -812,7 +815,6 @@ static int section_mismatch(const char *fromsec, const char *tosec)
return 0; return 0;
} }
/** /**
* Whitelist to allow certain references to pass with no warning. * Whitelist to allow certain references to pass with no warning.
* *
...@@ -856,36 +858,35 @@ static int section_mismatch(const char *fromsec, const char *tosec) ...@@ -856,36 +858,35 @@ static int section_mismatch(const char *fromsec, const char *tosec)
* refsymname = __init_begin, _sinittext, _einittext * refsymname = __init_begin, _sinittext, _einittext
* *
**/ **/
static int secref_whitelist(const char *modname, const char *tosec, static int secref_whitelist(const char *fromsec, const char *fromsym,
const char *fromsec, const char *atsym, const char *tosec, const char *tosym)
const char *refsymname)
{ {
/* Check for pattern 0 */ /* Check for pattern 0 */
if (match(fromsec, initref_sections)) if (match(fromsec, initref_sections))
return 1; return 0;
/* Check for pattern 1 */ /* Check for pattern 1 */
if (match(tosec, init_data_sections) && if (match(tosec, init_data_sections) &&
match(fromsec, data_sections) && match(fromsec, data_sections) &&
(strncmp(atsym, "__param", strlen("__param")) == 0)) (strncmp(fromsym, "__param", strlen("__param")) == 0))
return 1; return 0;
/* Check for pattern 2 */ /* Check for pattern 2 */
if (match(tosec, init_exit_sections) && if (match(tosec, init_exit_sections) &&
match(fromsec, data_sections) && match(fromsec, data_sections) &&
match(atsym, symbol_white_list)) match(fromsym, symbol_white_list))
return 1; return 0;
/* Check for pattern 3 */ /* Check for pattern 3 */
if (match(fromsec, head_sections) && if (match(fromsec, head_sections) &&
match(tosec, init_sections)) match(tosec, init_sections))
return 1; return 0;
/* Check for pattern 4 */ /* Check for pattern 4 */
if (match(refsymname, linker_symbols)) if (match(tosym, linker_symbols))
return 1; return 0;
return 0; return 1;
} }
/** /**
...@@ -987,41 +988,49 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, ...@@ -987,41 +988,49 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
return near; return near;
} }
/** /*
* Print a warning about a section mismatch. * Print a warning about a section mismatch.
* Try to find symbols near it so user can find it. * Try to find symbols near it so user can find it.
* Check whitelist before warning - it may be a false positive. * Check whitelist before warning - it may be a false positive.
**/ */
static void warn_sec_mismatch(const char *modname, const char *fromsec, static void report_sec_mismatch(const char *modname,
struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) const char *fromsec,
unsigned long long fromaddr,
const char *fromsym,
const char *tosec, const char *tosym)
{ {
Elf_Sym *where; if (strlen(tosym)) {
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) {
warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
"in '%s'\n", "in '%s'\n",
modname, fromsec, (unsigned long long)r.r_offset, modname, fromsec, fromaddr,
secname, refsymname, sym_name(elf, where)); tosec, tosym, fromsym);
} else { } else {
warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n", warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n",
modname, fromsec, (unsigned long long)r.r_offset, modname, fromsec, fromaddr,
secname, refsymname); 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, ...@@ -1107,7 +1116,6 @@ static void section_rela(const char *modname, struct elf_info *elf,
Elf_Rela r; Elf_Rela r;
unsigned int r_sym; unsigned int r_sym;
const char *fromsec; const char *fromsec;
const char * tosec;
Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset; Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset;
Elf_Rela *stop = (void *)start + sechdr->sh_size; Elf_Rela *stop = (void *)start + sechdr->sh_size;
...@@ -1117,7 +1125,6 @@ static void section_rela(const char *modname, struct elf_info *elf, ...@@ -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 from section (name) is know good then skip it */
if (match(fromsec, section_white_list)) if (match(fromsec, section_white_list))
return; return;
for (rela = start; rela < stop; rela++) { for (rela = start; rela < stop; rela++) {
r.r_offset = TO_NATIVE(rela->r_offset); r.r_offset = TO_NATIVE(rela->r_offset);
#if KERNEL_ELFCLASS == ELFCLASS64 #if KERNEL_ELFCLASS == ELFCLASS64
...@@ -1140,10 +1147,7 @@ static void section_rela(const char *modname, struct elf_info *elf, ...@@ -1140,10 +1147,7 @@ static void section_rela(const char *modname, struct elf_info *elf,
/* Skip special sections */ /* Skip special sections */
if (sym->st_shndx >= SHN_LORESERVE) if (sym->st_shndx >= SHN_LORESERVE)
continue; continue;
check_section_mismatch(modname, elf, &r, sym, fromsec);
tosec = sec_name(elf, sym->st_shndx);
if (section_mismatch(fromsec, tosec))
warn_sec_mismatch(modname, fromsec, elf, sym, r);
} }
} }
...@@ -1155,7 +1159,6 @@ static void section_rel(const char *modname, struct elf_info *elf, ...@@ -1155,7 +1159,6 @@ static void section_rel(const char *modname, struct elf_info *elf,
Elf_Rela r; Elf_Rela r;
unsigned int r_sym; unsigned int r_sym;
const char *fromsec; const char *fromsec;
const char * tosec;
Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset; Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset;
Elf_Rel *stop = (void *)start + sechdr->sh_size; Elf_Rel *stop = (void *)start + sechdr->sh_size;
...@@ -1202,10 +1205,7 @@ static void section_rel(const char *modname, struct elf_info *elf, ...@@ -1202,10 +1205,7 @@ static void section_rel(const char *modname, struct elf_info *elf,
/* Skip special sections */ /* Skip special sections */
if (sym->st_shndx >= SHN_LORESERVE) if (sym->st_shndx >= SHN_LORESERVE)
continue; continue;
check_section_mismatch(modname, elf, &r, sym, fromsec);
tosec = sec_name(elf, sym->st_shndx);
if (section_mismatch(fromsec, tosec))
warn_sec_mismatch(modname, fromsec, elf, sym, r);
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册