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: Sam Ravnborg <sam@ravnborg.org>
This commit is contained in:
parent
310f8243a6
commit
157c23c80e
|
@ -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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
|
|
||||||
/* 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 "
|
warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
|
||||||
"(between '%s' and '%s')\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 + 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 "
|
|
||||||
"before '%s' (at offset -0x%llx)\n",
|
|
||||||
modname, fromsec, (unsigned long long)r.r_offset,
|
|
||||||
secname, refsymname,
|
|
||||||
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,
|
||||||
|
|
Loading…
Reference in a new issue