|
@@ -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);
|
|
|
}
|
|
|
}
|
|
|
|