diff options
Diffstat (limited to 'scripts/mod')
-rw-r--r-- | scripts/mod/modpost.c | 68 |
1 files changed, 42 insertions, 26 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 8cef46b18dc6..0f48f8b97b17 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -930,6 +930,10 @@ struct sectioncheck { const char *good_tosec[20]; enum mismatch mismatch; const char *symbol_white_list[20]; + void (*handler)(const char *modname, struct elf_info *elf, + const struct sectioncheck* const mismatch, + Elf_Rela *r, Elf_Sym *sym, const char *fromsec); + }; static const struct sectioncheck sectioncheck[] = { @@ -1417,37 +1421,49 @@ static void report_sec_mismatch(const char *modname, fprintf(stderr, "\n"); } -static void check_section_mismatch(const char *modname, struct elf_info *elf, - Elf_Rela *r, Elf_Sym *sym, const char *fromsec) +static void default_mismatch_handler(const char *modname, struct elf_info *elf, + const struct sectioncheck* const mismatch, + Elf_Rela *r, Elf_Sym *sym, const char *fromsec) { const char *tosec; - const struct sectioncheck *mismatch; + Elf_Sym *to; + Elf_Sym *from; + const char *tosym; + const char *fromsym; tosec = sec_name(elf, get_secindex(elf, sym)); - mismatch = section_mismatch(fromsec, tosec); + from = find_elf_symbol2(elf, r->r_offset, fromsec); + fromsym = sym_name(elf, from); + to = find_elf_symbol(elf, r->r_addend, sym); + tosym = sym_name(elf, to); + + if (!strncmp(fromsym, "reference___initcall", + sizeof("reference___initcall")-1)) + return; + + /* check whitelist - we may ignore it */ + if (secref_whitelist(mismatch, + fromsec, fromsym, tosec, tosym)) { + report_sec_mismatch(modname, mismatch, + fromsec, r->r_offset, fromsym, + is_function(from), tosec, tosym, + is_function(to)); + } +} + +static void check_section_mismatch(const char *modname, struct elf_info *elf, + Elf_Rela *r, Elf_Sym *sym, const char *fromsec) +{ + const char *tosec = sec_name(elf, get_secindex(elf, sym));; + const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec); + if (mismatch) { - Elf_Sym *to; - Elf_Sym *from; - const char *tosym; - const char *fromsym; - - from = find_elf_symbol2(elf, r->r_offset, fromsec); - fromsym = sym_name(elf, from); - to = find_elf_symbol(elf, r->r_addend, sym); - tosym = sym_name(elf, to); - - if (!strncmp(fromsym, "reference___initcall", - sizeof("reference___initcall")-1)) - return; - - /* check whitelist - we may ignore it */ - if (secref_whitelist(mismatch, - fromsec, fromsym, tosec, tosym)) { - report_sec_mismatch(modname, mismatch, - fromsec, r->r_offset, fromsym, - is_function(from), tosec, tosym, - is_function(to)); - } + if (mismatch->handler) + mismatch->handler(modname, elf, mismatch, + r, sym, fromsec); + else + default_mismatch_handler(modname, elf, mismatch, + r, sym, fromsec); } } |