aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mod')
-rw-r--r--scripts/mod/modpost.c68
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 {
930 const char *good_tosec[20]; 930 const char *good_tosec[20];
931 enum mismatch mismatch; 931 enum mismatch mismatch;
932 const char *symbol_white_list[20]; 932 const char *symbol_white_list[20];
933 void (*handler)(const char *modname, struct elf_info *elf,
934 const struct sectioncheck* const mismatch,
935 Elf_Rela *r, Elf_Sym *sym, const char *fromsec);
936
933}; 937};
934 938
935static const struct sectioncheck sectioncheck[] = { 939static const struct sectioncheck sectioncheck[] = {
@@ -1417,37 +1421,49 @@ static void report_sec_mismatch(const char *modname,
1417 fprintf(stderr, "\n"); 1421 fprintf(stderr, "\n");
1418} 1422}
1419 1423
1420static void check_section_mismatch(const char *modname, struct elf_info *elf, 1424static void default_mismatch_handler(const char *modname, struct elf_info *elf,
1421 Elf_Rela *r, Elf_Sym *sym, const char *fromsec) 1425 const struct sectioncheck* const mismatch,
1426 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1422{ 1427{
1423 const char *tosec; 1428 const char *tosec;
1424 const struct sectioncheck *mismatch; 1429 Elf_Sym *to;
1430 Elf_Sym *from;
1431 const char *tosym;
1432 const char *fromsym;
1425 1433
1426 tosec = sec_name(elf, get_secindex(elf, sym)); 1434 tosec = sec_name(elf, get_secindex(elf, sym));
1427 mismatch = section_mismatch(fromsec, tosec); 1435 from = find_elf_symbol2(elf, r->r_offset, fromsec);
1436 fromsym = sym_name(elf, from);
1437 to = find_elf_symbol(elf, r->r_addend, sym);
1438 tosym = sym_name(elf, to);
1439
1440 if (!strncmp(fromsym, "reference___initcall",
1441 sizeof("reference___initcall")-1))
1442 return;
1443
1444 /* check whitelist - we may ignore it */
1445 if (secref_whitelist(mismatch,
1446 fromsec, fromsym, tosec, tosym)) {
1447 report_sec_mismatch(modname, mismatch,
1448 fromsec, r->r_offset, fromsym,
1449 is_function(from), tosec, tosym,
1450 is_function(to));
1451 }
1452}
1453
1454static void check_section_mismatch(const char *modname, struct elf_info *elf,
1455 Elf_Rela *r, Elf_Sym *sym, const char *fromsec)
1456{
1457 const char *tosec = sec_name(elf, get_secindex(elf, sym));;
1458 const struct sectioncheck *mismatch = section_mismatch(fromsec, tosec);
1459
1428 if (mismatch) { 1460 if (mismatch) {
1429 Elf_Sym *to; 1461 if (mismatch->handler)
1430 Elf_Sym *from; 1462 mismatch->handler(modname, elf, mismatch,
1431 const char *tosym; 1463 r, sym, fromsec);
1432 const char *fromsym; 1464 else
1433 1465 default_mismatch_handler(modname, elf, mismatch,
1434 from = find_elf_symbol2(elf, r->r_offset, fromsec); 1466 r, sym, fromsec);
1435 fromsym = sym_name(elf, from);
1436 to = find_elf_symbol(elf, r->r_addend, sym);
1437 tosym = sym_name(elf, to);
1438
1439 if (!strncmp(fromsym, "reference___initcall",
1440 sizeof("reference___initcall")-1))
1441 return;
1442
1443 /* check whitelist - we may ignore it */
1444 if (secref_whitelist(mismatch,
1445 fromsec, fromsym, tosec, tosym)) {
1446 report_sec_mismatch(modname, mismatch,
1447 fromsec, r->r_offset, fromsym,
1448 is_function(from), tosec, tosym,
1449 is_function(to));
1450 }
1451 } 1467 }
1452} 1468}
1453 1469