Loading scripts/mod/modpost.c +52 −52 Original line number Diff line number Diff line Loading @@ -607,7 +607,10 @@ static int strrcmp(const char *s, const char *sub) static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) { if (sym) return elf->strtab + sym->st_name; else return ""; } static const char *sec_name(struct elf_info *elf, int shndx) Loading Loading @@ -812,7 +815,6 @@ static int section_mismatch(const char *fromsec, const char *tosec) return 0; } /** * Whitelist to allow certain references to pass with no warning. * Loading Loading @@ -856,36 +858,35 @@ static int section_mismatch(const char *fromsec, const char *tosec) * refsymname = __init_begin, _sinittext, _einittext * **/ static int secref_whitelist(const char *modname, const char *tosec, const char *fromsec, const char *atsym, const char *refsymname) static int secref_whitelist(const char *fromsec, const char *fromsym, const char *tosec, const char *tosym) { /* Check for pattern 0 */ if (match(fromsec, initref_sections)) return 1; return 0; /* Check for pattern 1 */ if (match(tosec, init_data_sections) && match(fromsec, data_sections) && (strncmp(atsym, "__param", strlen("__param")) == 0)) return 1; (strncmp(fromsym, "__param", strlen("__param")) == 0)) return 0; /* Check for pattern 2 */ if (match(tosec, init_exit_sections) && match(fromsec, data_sections) && match(atsym, symbol_white_list)) return 1; match(fromsym, symbol_white_list)) return 0; /* Check for pattern 3 */ if (match(fromsec, head_sections) && match(tosec, init_sections)) return 1; return 0; /* Check for pattern 4 */ if (match(refsymname, linker_symbols)) return 1; if (match(tosym, linker_symbols)) return 0; return 1; } /** Loading Loading @@ -987,41 +988,49 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, return near; } /** /* * Print a warning about a section mismatch. * Try to find symbols near it so user can find it. * Check whitelist before warning - it may be a false positive. **/ static void warn_sec_mismatch(const char *modname, const char *fromsec, struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) */ static void report_sec_mismatch(const char *modname, const char *fromsec, unsigned long long fromaddr, const char *fromsym, const char *tosec, const char *tosym) { Elf_Sym *where; Elf_Sym *refsym; const char *refsymname = ""; const char *secname; secname = sec_name(elf, sym->st_shndx); where = find_elf_symbol2(elf, r.r_offset, fromsec); refsym = find_elf_symbol(elf, r.r_addend, sym); if (refsym && strlen(sym_name(elf, refsym))) refsymname = sym_name(elf, refsym); /* check whitelist - we may ignore it */ if (secref_whitelist(modname, secname, fromsec, where ? sym_name(elf, where) : "", refsymname)) return; if (where) { if (strlen(tosym)) { warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " "in '%s'\n", modname, fromsec, (unsigned long long)r.r_offset, secname, refsymname, sym_name(elf, where)); modname, fromsec, fromaddr, tosec, tosym, fromsym); } else { warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n", modname, fromsec, (unsigned long long)r.r_offset, secname, refsymname); modname, fromsec, fromaddr, tosec, tosym); } } static void check_section_mismatch(const char *modname, struct elf_info *elf, Elf_Rela *r, Elf_Sym *sym, const char *fromsec) { const char *tosec; tosec = sec_name(elf, sym->st_shndx); if (section_mismatch(fromsec, tosec)) { const char *fromsym; const char *tosym; fromsym = sym_name(elf, find_elf_symbol2(elf, r->r_offset, fromsec)); tosym = sym_name(elf, find_elf_symbol(elf, r->r_addend, sym)); /* check whitelist - we may ignore it */ if (secref_whitelist(fromsec, fromsym, tosec, tosym)) { report_sec_mismatch(modname, fromsec, r->r_offset, fromsym, tosec, tosym); } } } Loading Loading @@ -1107,7 +1116,6 @@ static void section_rela(const char *modname, struct elf_info *elf, Elf_Rela r; unsigned int r_sym; const char *fromsec; const char * tosec; Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset; Elf_Rela *stop = (void *)start + sechdr->sh_size; Loading @@ -1117,7 +1125,6 @@ static void section_rela(const char *modname, struct elf_info *elf, /* if from section (name) is know good then skip it */ if (match(fromsec, section_white_list)) return; for (rela = start; rela < stop; rela++) { r.r_offset = TO_NATIVE(rela->r_offset); #if KERNEL_ELFCLASS == ELFCLASS64 Loading @@ -1140,10 +1147,7 @@ static void section_rela(const char *modname, struct elf_info *elf, /* Skip special sections */ if (sym->st_shndx >= SHN_LORESERVE) continue; tosec = sec_name(elf, sym->st_shndx); if (section_mismatch(fromsec, tosec)) warn_sec_mismatch(modname, fromsec, elf, sym, r); check_section_mismatch(modname, elf, &r, sym, fromsec); } } Loading @@ -1155,7 +1159,6 @@ static void section_rel(const char *modname, struct elf_info *elf, Elf_Rela r; unsigned int r_sym; const char *fromsec; const char * tosec; Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset; Elf_Rel *stop = (void *)start + sechdr->sh_size; Loading Loading @@ -1202,10 +1205,7 @@ static void section_rel(const char *modname, struct elf_info *elf, /* Skip special sections */ if (sym->st_shndx >= SHN_LORESERVE) continue; tosec = sec_name(elf, sym->st_shndx); if (section_mismatch(fromsec, tosec)) warn_sec_mismatch(modname, fromsec, elf, sym, r); check_section_mismatch(modname, elf, &r, sym, fromsec); } } Loading Loading
scripts/mod/modpost.c +52 −52 Original line number Diff line number Diff line Loading @@ -607,7 +607,10 @@ static int strrcmp(const char *s, const char *sub) static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) { if (sym) return elf->strtab + sym->st_name; else return ""; } static const char *sec_name(struct elf_info *elf, int shndx) Loading Loading @@ -812,7 +815,6 @@ static int section_mismatch(const char *fromsec, const char *tosec) return 0; } /** * Whitelist to allow certain references to pass with no warning. * Loading Loading @@ -856,36 +858,35 @@ static int section_mismatch(const char *fromsec, const char *tosec) * refsymname = __init_begin, _sinittext, _einittext * **/ static int secref_whitelist(const char *modname, const char *tosec, const char *fromsec, const char *atsym, const char *refsymname) static int secref_whitelist(const char *fromsec, const char *fromsym, const char *tosec, const char *tosym) { /* Check for pattern 0 */ if (match(fromsec, initref_sections)) return 1; return 0; /* Check for pattern 1 */ if (match(tosec, init_data_sections) && match(fromsec, data_sections) && (strncmp(atsym, "__param", strlen("__param")) == 0)) return 1; (strncmp(fromsym, "__param", strlen("__param")) == 0)) return 0; /* Check for pattern 2 */ if (match(tosec, init_exit_sections) && match(fromsec, data_sections) && match(atsym, symbol_white_list)) return 1; match(fromsym, symbol_white_list)) return 0; /* Check for pattern 3 */ if (match(fromsec, head_sections) && match(tosec, init_sections)) return 1; return 0; /* Check for pattern 4 */ if (match(refsymname, linker_symbols)) return 1; if (match(tosym, linker_symbols)) return 0; return 1; } /** Loading Loading @@ -987,41 +988,49 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, return near; } /** /* * Print a warning about a section mismatch. * Try to find symbols near it so user can find it. * Check whitelist before warning - it may be a false positive. **/ static void warn_sec_mismatch(const char *modname, const char *fromsec, struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) */ static void report_sec_mismatch(const char *modname, const char *fromsec, unsigned long long fromaddr, const char *fromsym, const char *tosec, const char *tosym) { Elf_Sym *where; Elf_Sym *refsym; const char *refsymname = ""; const char *secname; secname = sec_name(elf, sym->st_shndx); where = find_elf_symbol2(elf, r.r_offset, fromsec); refsym = find_elf_symbol(elf, r.r_addend, sym); if (refsym && strlen(sym_name(elf, refsym))) refsymname = sym_name(elf, refsym); /* check whitelist - we may ignore it */ if (secref_whitelist(modname, secname, fromsec, where ? sym_name(elf, where) : "", refsymname)) return; if (where) { if (strlen(tosym)) { warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " "in '%s'\n", modname, fromsec, (unsigned long long)r.r_offset, secname, refsymname, sym_name(elf, where)); modname, fromsec, fromaddr, tosec, tosym, fromsym); } else { warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n", modname, fromsec, (unsigned long long)r.r_offset, secname, refsymname); modname, fromsec, fromaddr, tosec, tosym); } } static void check_section_mismatch(const char *modname, struct elf_info *elf, Elf_Rela *r, Elf_Sym *sym, const char *fromsec) { const char *tosec; tosec = sec_name(elf, sym->st_shndx); if (section_mismatch(fromsec, tosec)) { const char *fromsym; const char *tosym; fromsym = sym_name(elf, find_elf_symbol2(elf, r->r_offset, fromsec)); tosym = sym_name(elf, find_elf_symbol(elf, r->r_addend, sym)); /* check whitelist - we may ignore it */ if (secref_whitelist(fromsec, fromsym, tosec, tosym)) { report_sec_mismatch(modname, fromsec, r->r_offset, fromsym, tosec, tosym); } } } Loading Loading @@ -1107,7 +1116,6 @@ static void section_rela(const char *modname, struct elf_info *elf, Elf_Rela r; unsigned int r_sym; const char *fromsec; const char * tosec; Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset; Elf_Rela *stop = (void *)start + sechdr->sh_size; Loading @@ -1117,7 +1125,6 @@ static void section_rela(const char *modname, struct elf_info *elf, /* if from section (name) is know good then skip it */ if (match(fromsec, section_white_list)) return; for (rela = start; rela < stop; rela++) { r.r_offset = TO_NATIVE(rela->r_offset); #if KERNEL_ELFCLASS == ELFCLASS64 Loading @@ -1140,10 +1147,7 @@ static void section_rela(const char *modname, struct elf_info *elf, /* Skip special sections */ if (sym->st_shndx >= SHN_LORESERVE) continue; tosec = sec_name(elf, sym->st_shndx); if (section_mismatch(fromsec, tosec)) warn_sec_mismatch(modname, fromsec, elf, sym, r); check_section_mismatch(modname, elf, &r, sym, fromsec); } } Loading @@ -1155,7 +1159,6 @@ static void section_rel(const char *modname, struct elf_info *elf, Elf_Rela r; unsigned int r_sym; const char *fromsec; const char * tosec; Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset; Elf_Rel *stop = (void *)start + sechdr->sh_size; Loading Loading @@ -1202,10 +1205,7 @@ static void section_rel(const char *modname, struct elf_info *elf, /* Skip special sections */ if (sym->st_shndx >= SHN_LORESERVE) continue; tosec = sec_name(elf, sym->st_shndx); if (section_mismatch(fromsec, tosec)) warn_sec_mismatch(modname, fromsec, elf, sym, r); check_section_mismatch(modname, elf, &r, sym, fromsec); } } Loading