aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod/modpost.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mod/modpost.c')
-rw-r--r--scripts/mod/modpost.c105
1 files changed, 80 insertions, 25 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 7e8079a34adf..d0f86ed43f7a 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -487,22 +487,24 @@ static int strrcmp(const char *s, const char *sub)
487 * atsym =__param* 487 * atsym =__param*
488 * 488 *
489 * Pattern 2: 489 * Pattern 2:
490 * Many drivers utilise a *_driver container with references to 490 * Many drivers utilise a *driver container with references to
491 * add, remove, probe functions etc. 491 * add, remove, probe functions etc.
492 * These functions may often be marked __init and we do not want to 492 * These functions may often be marked __init and we do not want to
493 * warn here. 493 * warn here.
494 * the pattern is identified by: 494 * the pattern is identified by:
495 * tosec = .init.text | .exit.text 495 * tosec = .init.text | .exit.text | .init.data
496 * fromsec = .data 496 * fromsec = .data
497 * atsym = *_driver, *_ops, *_probe, *probe_one 497 * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one
498 **/ 498 **/
499static int secref_whitelist(const char *tosec, const char *fromsec, 499static int secref_whitelist(const char *tosec, const char *fromsec,
500 const char *atsym) 500 const char *atsym)
501{ 501{
502 int f1 = 1, f2 = 1; 502 int f1 = 1, f2 = 1;
503 const char **s; 503 const char **s;
504 const char *pat2sym[] = { 504 const char *pat2sym[] = {
505 "_driver", 505 "driver",
506 "_template", /* scsi uses *_template a lot */
507 "_sht", /* scsi also used *_sht to some extent */
506 "_ops", 508 "_ops",
507 "_probe", 509 "_probe",
508 "_probe_one", 510 "_probe_one",
@@ -522,7 +524,8 @@ static int secref_whitelist(const char *tosec, const char *fromsec,
522 524
523 /* Check for pattern 2 */ 525 /* Check for pattern 2 */
524 if ((strcmp(tosec, ".init.text") != 0) && 526 if ((strcmp(tosec, ".init.text") != 0) &&
525 (strcmp(tosec, ".exit.text") != 0)) 527 (strcmp(tosec, ".exit.text") != 0) &&
528 (strcmp(tosec, ".init.data") != 0))
526 f2 = 0; 529 f2 = 0;
527 if (strcmp(fromsec, ".data") != 0) 530 if (strcmp(fromsec, ".data") != 0)
528 f2 = 0; 531 f2 = 0;
@@ -694,29 +697,79 @@ static void check_sec_ref(struct module *mod, const char *modname,
694 697
695 /* Walk through all sections */ 698 /* Walk through all sections */
696 for (i = 0; i < hdr->e_shnum; i++) { 699 for (i = 0; i < hdr->e_shnum; i++) {
697 Elf_Rela *rela; 700 const char *name = secstrings + sechdrs[i].sh_name;
698 Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset; 701 const char *secname;
699 Elf_Rela *stop = (void*)start + sechdrs[i].sh_size; 702 Elf_Rela r;
700 const char *name = secstrings + sechdrs[i].sh_name + 703 unsigned int r_sym;
701 strlen(".rela");
702 /* We want to process only relocation sections and not .init */ 704 /* We want to process only relocation sections and not .init */
703 if (section_ref_ok(name) || (sechdrs[i].sh_type != SHT_RELA)) 705 if (sechdrs[i].sh_type == SHT_RELA) {
704 continue; 706 Elf_Rela *rela;
707 Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset;
708 Elf_Rela *stop = (void*)start + sechdrs[i].sh_size;
709 name += strlen(".rela");
710 if (section_ref_ok(name))
711 continue;
705 712
706 for (rela = start; rela < stop; rela++) { 713 for (rela = start; rela < stop; rela++) {
707 Elf_Rela r; 714 r.r_offset = TO_NATIVE(rela->r_offset);
708 const char *secname; 715#if KERNEL_ELFCLASS == ELFCLASS64
709 r.r_offset = TO_NATIVE(rela->r_offset); 716 if (hdr->e_machine == EM_MIPS) {
710 r.r_info = TO_NATIVE(rela->r_info); 717 r_sym = ELF64_MIPS_R_SYM(rela->r_info);
711 r.r_addend = TO_NATIVE(rela->r_addend); 718 r_sym = TO_NATIVE(r_sym);
712 sym = elf->symtab_start + ELF_R_SYM(r.r_info); 719 } else {
713 /* Skip special sections */ 720 r.r_info = TO_NATIVE(rela->r_info);
714 if (sym->st_shndx >= SHN_LORESERVE) 721 r_sym = ELF_R_SYM(r.r_info);
722 }
723#else
724 r.r_info = TO_NATIVE(rela->r_info);
725 r_sym = ELF_R_SYM(r.r_info);
726#endif
727 r.r_addend = TO_NATIVE(rela->r_addend);
728 sym = elf->symtab_start + r_sym;
729 /* Skip special sections */
730 if (sym->st_shndx >= SHN_LORESERVE)
731 continue;
732
733 secname = secstrings +
734 sechdrs[sym->st_shndx].sh_name;
735 if (section(secname))
736 warn_sec_mismatch(modname, name,
737 elf, sym, r);
738 }
739 } else if (sechdrs[i].sh_type == SHT_REL) {
740 Elf_Rel *rel;
741 Elf_Rel *start = (void *)hdr + sechdrs[i].sh_offset;
742 Elf_Rel *stop = (void*)start + sechdrs[i].sh_size;
743 name += strlen(".rel");
744 if (section_ref_ok(name))
715 continue; 745 continue;
716 746
717 secname = secstrings + sechdrs[sym->st_shndx].sh_name; 747 for (rel = start; rel < stop; rel++) {
718 if (section(secname)) 748 r.r_offset = TO_NATIVE(rel->r_offset);
719 warn_sec_mismatch(modname, name, elf, sym, r); 749#if KERNEL_ELFCLASS == ELFCLASS64
750 if (hdr->e_machine == EM_MIPS) {
751 r_sym = ELF64_MIPS_R_SYM(rel->r_info);
752 r_sym = TO_NATIVE(r_sym);
753 } else {
754 r.r_info = TO_NATIVE(rel->r_info);
755 r_sym = ELF_R_SYM(r.r_info);
756 }
757#else
758 r.r_info = TO_NATIVE(rel->r_info);
759 r_sym = ELF_R_SYM(r.r_info);
760#endif
761 r.r_addend = 0;
762 sym = elf->symtab_start + r_sym;
763 /* Skip special sections */
764 if (sym->st_shndx >= SHN_LORESERVE)
765 continue;
766
767 secname = secstrings +
768 sechdrs[sym->st_shndx].sh_name;
769 if (section(secname))
770 warn_sec_mismatch(modname, name,
771 elf, sym, r);
772 }
720 } 773 }
721 } 774 }
722} 775}
@@ -820,6 +873,7 @@ static int exit_section(const char *name)
820 * For our future {in}sanity, add a comment that this is the ppc .opd 873 * For our future {in}sanity, add a comment that this is the ppc .opd
821 * section, not the ia64 .opd section. 874 * section, not the ia64 .opd section.
822 * ia64 .opd should not point to discarded sections. 875 * ia64 .opd should not point to discarded sections.
876 * [.rodata] like for .init.text we ignore .rodata references -same reason
823 **/ 877 **/
824static int exit_section_ref_ok(const char *name) 878static int exit_section_ref_ok(const char *name)
825{ 879{
@@ -829,6 +883,7 @@ static int exit_section_ref_ok(const char *name)
829 ".exit.text", 883 ".exit.text",
830 ".exit.data", 884 ".exit.data",
831 ".init.text", 885 ".init.text",
886 ".rodata",
832 ".opd", /* See comment [OPD] */ 887 ".opd", /* See comment [OPD] */
833 ".toc1", /* used by ppc64 */ 888 ".toc1", /* used by ppc64 */
834 ".altinstructions", 889 ".altinstructions",