Commit 157c23c8 authored by Sam Ravnborg's avatar Sam Ravnborg

kbuild: use simpler section mismatch warnings in modpost

The typical layout is now:
WARNING: vmlinux.o(.text+0x372ec): Section mismatch: reference to .devinit.text:pci_scan_one_pbm in 'psycho_scan_bus'

This is first step towards more readable warnings.
Signed-off-by: default avatarSam Ravnborg <sam@ravnborg.org>
parent 310f8243
...@@ -938,20 +938,16 @@ static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym) ...@@ -938,20 +938,16 @@ static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
* The ELF format may have a better way to detect what type of symbol * The ELF format may have a better way to detect what type of symbol
* it is, but this works for now. * it is, but this works for now.
**/ **/
static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
const char *sec, const char *sec)
Elf_Sym **before, Elf_Sym **after)
{ {
Elf_Sym *sym; Elf_Sym *sym;
Elf_Sym *near = NULL;
Elf_Ehdr *hdr = elf->hdr; Elf_Ehdr *hdr = elf->hdr;
Elf_Addr beforediff = ~0; Elf_Addr distance = ~0;
Elf_Addr afterdiff = ~0;
const char *secstrings = (void *)hdr + const char *secstrings = (void *)hdr +
elf->sechdrs[hdr->e_shstrndx].sh_offset; elf->sechdrs[hdr->e_shstrndx].sh_offset;
*before = NULL;
*after = NULL;
for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
const char *symsec; const char *symsec;
...@@ -963,20 +959,15 @@ static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, ...@@ -963,20 +959,15 @@ static void find_symbols_between(struct elf_info *elf, Elf_Addr addr,
if (!is_valid_name(elf, sym)) if (!is_valid_name(elf, sym))
continue; continue;
if (sym->st_value <= addr) { if (sym->st_value <= addr) {
if ((addr - sym->st_value) < beforediff) { if ((addr - sym->st_value) < distance) {
beforediff = addr - sym->st_value; distance = addr - sym->st_value;
*before = sym; near = sym;
} else if ((addr - sym->st_value) == beforediff) { } else if ((addr - sym->st_value) == distance) {
*before = sym; near = sym;
} }
} else {
if ((sym->st_value - addr) < afterdiff) {
afterdiff = sym->st_value - addr;
*after = sym;
} else if ((sym->st_value - addr) == afterdiff)
*after = sym;
} }
} }
return near;
} }
/** /**
...@@ -988,7 +979,7 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, ...@@ -988,7 +979,7 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec,
struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) struct elf_info *elf, Elf_Sym *sym, Elf_Rela r)
{ {
const char *refsymname = ""; const char *refsymname = "";
Elf_Sym *before, *after; Elf_Sym *where;
Elf_Sym *refsym; Elf_Sym *refsym;
Elf_Ehdr *hdr = elf->hdr; Elf_Ehdr *hdr = elf->hdr;
Elf_Shdr *sechdrs = elf->sechdrs; Elf_Shdr *sechdrs = elf->sechdrs;
...@@ -996,7 +987,7 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, ...@@ -996,7 +987,7 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec,
sechdrs[hdr->e_shstrndx].sh_offset; sechdrs[hdr->e_shstrndx].sh_offset;
const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name; const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name;
find_symbols_between(elf, r.r_offset, fromsec, &before, &after); where = find_elf_symbol2(elf, r.r_offset, fromsec);
refsym = find_elf_symbol(elf, r.r_addend, sym); refsym = find_elf_symbol(elf, r.r_addend, sym);
if (refsym && strlen(elf->strtab + refsym->st_name)) if (refsym && strlen(elf->strtab + refsym->st_name))
...@@ -1004,30 +995,15 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, ...@@ -1004,30 +995,15 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec,
/* check whitelist - we may ignore it */ /* check whitelist - we may ignore it */
if (secref_whitelist(modname, secname, fromsec, if (secref_whitelist(modname, secname, fromsec,
before ? elf->strtab + before->st_name : "", where ? elf->strtab + where->st_name : "",
refsymname)) refsymname))
return; return;
if (before && after) { if (where) {
warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
"(between '%s' and '%s')\n",
modname, fromsec, (unsigned long long)r.r_offset,
secname, refsymname,
elf->strtab + before->st_name,
elf->strtab + after->st_name);
} else if (before) {
warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
"(after '%s')\n",
modname, fromsec, (unsigned long long)r.r_offset,
secname, refsymname,
elf->strtab + before->st_name);
} else if (after) {
warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
"before '%s' (at offset -0x%llx)\n", "in '%s'\n",
modname, fromsec, (unsigned long long)r.r_offset, modname, fromsec, (unsigned long long)r.r_offset,
secname, refsymname, secname, refsymname, elf->strtab + where->st_name);
elf->strtab + after->st_name,
(unsigned long long)r.r_offset);
} 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, (unsigned long long)r.r_offset,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment