diff options
Diffstat (limited to 'scripts/mod/modpost.c')
-rw-r--r-- | scripts/mod/modpost.c | 65 |
1 files changed, 46 insertions, 19 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 6d04504b2fc1..1aa52a86c2cf 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -697,29 +697,56 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
697 | 697 | ||
698 | /* Walk through all sections */ | 698 | /* Walk through all sections */ |
699 | for (i = 0; i < hdr->e_shnum; i++) { | 699 | for (i = 0; i < hdr->e_shnum; i++) { |
700 | Elf_Rela *rela; | 700 | const char *name = secstrings + sechdrs[i].sh_name; |
701 | Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset; | 701 | const char *secname; |
702 | Elf_Rela *stop = (void*)start + sechdrs[i].sh_size; | 702 | Elf_Rela r; |
703 | const char *name = secstrings + sechdrs[i].sh_name + | ||
704 | strlen(".rela"); | ||
705 | /* We want to process only relocation sections and not .init */ | 703 | /* We want to process only relocation sections and not .init */ |
706 | if (section_ref_ok(name) || (sechdrs[i].sh_type != SHT_RELA)) | 704 | if (sechdrs[i].sh_type == SHT_RELA) { |
707 | continue; | 705 | Elf_Rela *rela; |
706 | Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset; | ||
707 | Elf_Rela *stop = (void*)start + sechdrs[i].sh_size; | ||
708 | name += strlen(".rela"); | ||
709 | if (section_ref_ok(name)) | ||
710 | continue; | ||
708 | 711 | ||
709 | for (rela = start; rela < stop; rela++) { | 712 | for (rela = start; rela < stop; rela++) { |
710 | Elf_Rela r; | 713 | r.r_offset = TO_NATIVE(rela->r_offset); |
711 | const char *secname; | 714 | r.r_info = TO_NATIVE(rela->r_info); |
712 | r.r_offset = TO_NATIVE(rela->r_offset); | 715 | r.r_addend = TO_NATIVE(rela->r_addend); |
713 | r.r_info = TO_NATIVE(rela->r_info); | 716 | sym = elf->symtab_start + ELF_R_SYM(r.r_info); |
714 | r.r_addend = TO_NATIVE(rela->r_addend); | 717 | /* Skip special sections */ |
715 | sym = elf->symtab_start + ELF_R_SYM(r.r_info); | 718 | if (sym->st_shndx >= SHN_LORESERVE) |
716 | /* Skip special sections */ | 719 | continue; |
717 | if (sym->st_shndx >= SHN_LORESERVE) | 720 | |
721 | secname = secstrings + | ||
722 | sechdrs[sym->st_shndx].sh_name; | ||
723 | if (section(secname)) | ||
724 | warn_sec_mismatch(modname, name, | ||
725 | elf, sym, r); | ||
726 | } | ||
727 | } else if (sechdrs[i].sh_type == SHT_REL) { | ||
728 | Elf_Rel *rel; | ||
729 | Elf_Rel *start = (void *)hdr + sechdrs[i].sh_offset; | ||
730 | Elf_Rel *stop = (void*)start + sechdrs[i].sh_size; | ||
731 | name += strlen(".rel"); | ||
732 | if (section_ref_ok(name)) | ||
718 | continue; | 733 | continue; |
719 | 734 | ||
720 | secname = secstrings + sechdrs[sym->st_shndx].sh_name; | 735 | for (rel = start; rel < stop; rel++) { |
721 | if (section(secname)) | 736 | r.r_offset = TO_NATIVE(rel->r_offset); |
722 | warn_sec_mismatch(modname, name, elf, sym, r); | 737 | r.r_info = TO_NATIVE(rel->r_info); |
738 | r.r_addend = 0; | ||
739 | sym = elf->symtab_start + ELF_R_SYM(r.r_info); | ||
740 | /* Skip special sections */ | ||
741 | if (sym->st_shndx >= SHN_LORESERVE) | ||
742 | continue; | ||
743 | |||
744 | secname = secstrings + | ||
745 | sechdrs[sym->st_shndx].sh_name; | ||
746 | if (section(secname)) | ||
747 | warn_sec_mismatch(modname, name, | ||
748 | elf, sym, r); | ||
749 | } | ||
723 | } | 750 | } |
724 | } | 751 | } |
725 | } | 752 | } |