Loading scripts/mod/modpost.c +47 −17 Original line number Diff line number Diff line Loading @@ -451,6 +451,29 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, return NULL; } /** * Find symbol based on relocation record info. * In some cases the symbol supplied is a valid symbol so * return refsym. If st_name != 0 we assume this is a valid symbol. * In other cases the symbol needs to be looked up in the symbol table * based on section and address. * **/ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, Elf_Sym *relsym) { Elf_Sym *sym; if (relsym->st_name != 0) return relsym; for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { if (sym->st_shndx != relsym->st_shndx) continue; if (sym->st_value == addr) return sym; } return NULL; } /* * Find symbols before or equal addr and after addr - in the section sec **/ Loading Loading @@ -499,8 +522,9 @@ static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, static void warn_sec_mismatch(const char *modname, const char *fromsec, struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) { Elf_Sym *before; Elf_Sym *after; const char *refsymname = ""; Elf_Sym *before, *after; Elf_Sym *refsym; Elf_Ehdr *hdr = elf->hdr; Elf_Shdr *sechdrs = elf->sechdrs; const char *secstrings = (void *)hdr + Loading @@ -509,29 +533,34 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, find_symbols_between(elf, r.r_offset, fromsec, &before, &after); refsym = find_elf_symbol(elf, r.r_addend, sym); if (refsym && strlen(elf->strtab + refsym->st_name)) refsymname = elf->strtab + refsym->st_name; if (before && after) { warn("%s - Section mismatch: reference to %s from %s " "between '%s' (at offset 0x%lx) and '%s'\n", modname, secname, fromsec, warn("%s - Section mismatch: reference to %s:%s from %s " "between '%s' (at offset 0x%llx) and '%s'\n", modname, secname, refsymname, fromsec, elf->strtab + before->st_name, (long)(r.r_offset - before->st_value), (long long)r.r_offset, elf->strtab + after->st_name); } else if (before) { warn("%s - Section mismatch: reference to %s from %s " "after '%s' (at offset 0x%lx)\n", modname, secname, fromsec, warn("%s - Section mismatch: reference to %s:%s from %s " "after '%s' (at offset 0x%llx)\n", modname, secname, refsymname, fromsec, elf->strtab + before->st_name, (long)(r.r_offset - before->st_value)); (long long)r.r_offset); } else if (after) { warn("%s - Section mismatch: reference to %s from %s " "before '%s' (at offset -0x%lx)\n", modname, secname, fromsec, warn("%s - Section mismatch: reference to %s:%s from %s " "before '%s' (at offset -0x%llx)\n", modname, secname, refsymname, fromsec, elf->strtab + before->st_name, (long)(before->st_value - r.r_offset)); (long long)r.r_offset); } else { warn("%s - Section mismatch: reference to %s from %s " "(offset 0x%lx)\n", modname, secname, fromsec, (long)r.r_offset); warn("%s - Section mismatch: reference to %s:%s from %s " "(offset 0x%llx)\n", modname, secname, fromsec, refsymname, (long long)r.r_offset); } } Loading Loading @@ -575,6 +604,7 @@ static void check_sec_ref(struct module *mod, const char *modname, const char *secname; r.r_offset = TO_NATIVE(rela->r_offset); r.r_info = TO_NATIVE(rela->r_info); r.r_addend = TO_NATIVE(rela->r_addend); sym = elf->symtab_start + ELF_R_SYM(r.r_info); /* Skip special sections */ if (sym->st_shndx >= SHN_LORESERVE) Loading Loading
scripts/mod/modpost.c +47 −17 Original line number Diff line number Diff line Loading @@ -451,6 +451,29 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, return NULL; } /** * Find symbol based on relocation record info. * In some cases the symbol supplied is a valid symbol so * return refsym. If st_name != 0 we assume this is a valid symbol. * In other cases the symbol needs to be looked up in the symbol table * based on section and address. * **/ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr, Elf_Sym *relsym) { Elf_Sym *sym; if (relsym->st_name != 0) return relsym; for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { if (sym->st_shndx != relsym->st_shndx) continue; if (sym->st_value == addr) return sym; } return NULL; } /* * Find symbols before or equal addr and after addr - in the section sec **/ Loading Loading @@ -499,8 +522,9 @@ static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, static void warn_sec_mismatch(const char *modname, const char *fromsec, struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) { Elf_Sym *before; Elf_Sym *after; const char *refsymname = ""; Elf_Sym *before, *after; Elf_Sym *refsym; Elf_Ehdr *hdr = elf->hdr; Elf_Shdr *sechdrs = elf->sechdrs; const char *secstrings = (void *)hdr + Loading @@ -509,29 +533,34 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, find_symbols_between(elf, r.r_offset, fromsec, &before, &after); refsym = find_elf_symbol(elf, r.r_addend, sym); if (refsym && strlen(elf->strtab + refsym->st_name)) refsymname = elf->strtab + refsym->st_name; if (before && after) { warn("%s - Section mismatch: reference to %s from %s " "between '%s' (at offset 0x%lx) and '%s'\n", modname, secname, fromsec, warn("%s - Section mismatch: reference to %s:%s from %s " "between '%s' (at offset 0x%llx) and '%s'\n", modname, secname, refsymname, fromsec, elf->strtab + before->st_name, (long)(r.r_offset - before->st_value), (long long)r.r_offset, elf->strtab + after->st_name); } else if (before) { warn("%s - Section mismatch: reference to %s from %s " "after '%s' (at offset 0x%lx)\n", modname, secname, fromsec, warn("%s - Section mismatch: reference to %s:%s from %s " "after '%s' (at offset 0x%llx)\n", modname, secname, refsymname, fromsec, elf->strtab + before->st_name, (long)(r.r_offset - before->st_value)); (long long)r.r_offset); } else if (after) { warn("%s - Section mismatch: reference to %s from %s " "before '%s' (at offset -0x%lx)\n", modname, secname, fromsec, warn("%s - Section mismatch: reference to %s:%s from %s " "before '%s' (at offset -0x%llx)\n", modname, secname, refsymname, fromsec, elf->strtab + before->st_name, (long)(before->st_value - r.r_offset)); (long long)r.r_offset); } else { warn("%s - Section mismatch: reference to %s from %s " "(offset 0x%lx)\n", modname, secname, fromsec, (long)r.r_offset); warn("%s - Section mismatch: reference to %s:%s from %s " "(offset 0x%llx)\n", modname, secname, fromsec, refsymname, (long long)r.r_offset); } } Loading Loading @@ -575,6 +604,7 @@ static void check_sec_ref(struct module *mod, const char *modname, const char *secname; r.r_offset = TO_NATIVE(rela->r_offset); r.r_info = TO_NATIVE(rela->r_info); r.r_addend = TO_NATIVE(rela->r_addend); sym = elf->symtab_start + ELF_R_SYM(r.r_info); /* Skip special sections */ if (sym->st_shndx >= SHN_LORESERVE) Loading