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.c56
1 files changed, 16 insertions, 40 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index 730b321680cd..7dfd0395c5b0 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -938,20 +938,16 @@ static inline int is_valid_name(struct elf_info *elf, Elf_Sym *sym)
938 * The ELF format may have a better way to detect what type of symbol 938 * The ELF format may have a better way to detect what type of symbol
939 * it is, but this works for now. 939 * it is, but this works for now.
940 **/ 940 **/
941static void find_symbols_between(struct elf_info *elf, Elf_Addr addr, 941static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
942 const char *sec, 942 const char *sec)
943 Elf_Sym **before, Elf_Sym **after)
944{ 943{
945 Elf_Sym *sym; 944 Elf_Sym *sym;
945 Elf_Sym *near = NULL;
946 Elf_Ehdr *hdr = elf->hdr; 946 Elf_Ehdr *hdr = elf->hdr;
947 Elf_Addr beforediff = ~0; 947 Elf_Addr distance = ~0;
948 Elf_Addr afterdiff = ~0;
949 const char *secstrings = (void *)hdr + 948 const char *secstrings = (void *)hdr +
950 elf->sechdrs[hdr->e_shstrndx].sh_offset; 949 elf->sechdrs[hdr->e_shstrndx].sh_offset;
951 950
952 *before = NULL;
953 *after = NULL;
954
955 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) { 951 for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
956 const char *symsec; 952 const char *symsec;
957 953
@@ -963,20 +959,15 @@ static void find_symbols_between(struct elf_info *elf, Elf_Addr addr,
963 if (!is_valid_name(elf, sym)) 959 if (!is_valid_name(elf, sym))
964 continue; 960 continue;
965 if (sym->st_value <= addr) { 961 if (sym->st_value <= addr) {
966 if ((addr - sym->st_value) < beforediff) { 962 if ((addr - sym->st_value) < distance) {
967 beforediff = addr - sym->st_value; 963 distance = addr - sym->st_value;
968 *before = sym; 964 near = sym;
969 } else if ((addr - sym->st_value) == beforediff) { 965 } else if ((addr - sym->st_value) == distance) {
970 *before = sym; 966 near = sym;
971 } 967 }
972 } else {
973 if ((sym->st_value - addr) < afterdiff) {
974 afterdiff = sym->st_value - addr;
975 *after = sym;
976 } else if ((sym->st_value - addr) == afterdiff)
977 *after = sym;
978 } 968 }
979 } 969 }
970 return near;
980} 971}
981 972
982/** 973/**
@@ -988,7 +979,7 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec,
988 struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) 979 struct elf_info *elf, Elf_Sym *sym, Elf_Rela r)
989{ 980{
990 const char *refsymname = ""; 981 const char *refsymname = "";
991 Elf_Sym *before, *after; 982 Elf_Sym *where;
992 Elf_Sym *refsym; 983 Elf_Sym *refsym;
993 Elf_Ehdr *hdr = elf->hdr; 984 Elf_Ehdr *hdr = elf->hdr;
994 Elf_Shdr *sechdrs = elf->sechdrs; 985 Elf_Shdr *sechdrs = elf->sechdrs;
@@ -996,7 +987,7 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec,
996 sechdrs[hdr->e_shstrndx].sh_offset; 987 sechdrs[hdr->e_shstrndx].sh_offset;
997 const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name; 988 const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name;
998 989
999 find_symbols_between(elf, r.r_offset, fromsec, &before, &after); 990 where = find_elf_symbol2(elf, r.r_offset, fromsec);
1000 991
1001 refsym = find_elf_symbol(elf, r.r_addend, sym); 992 refsym = find_elf_symbol(elf, r.r_addend, sym);
1002 if (refsym && strlen(elf->strtab + refsym->st_name)) 993 if (refsym && strlen(elf->strtab + refsym->st_name))
@@ -1004,30 +995,15 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec,
1004 995
1005 /* check whitelist - we may ignore it */ 996 /* check whitelist - we may ignore it */
1006 if (secref_whitelist(modname, secname, fromsec, 997 if (secref_whitelist(modname, secname, fromsec,
1007 before ? elf->strtab + before->st_name : "", 998 where ? elf->strtab + where->st_name : "",
1008 refsymname)) 999 refsymname))
1009 return; 1000 return;
1010 1001
1011 if (before && after) { 1002 if (where) {
1012 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
1013 "(between '%s' and '%s')\n",
1014 modname, fromsec, (unsigned long long)r.r_offset,
1015 secname, refsymname,
1016 elf->strtab + before->st_name,
1017 elf->strtab + after->st_name);
1018 } else if (before) {
1019 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
1020 "(after '%s')\n",
1021 modname, fromsec, (unsigned long long)r.r_offset,
1022 secname, refsymname,
1023 elf->strtab + before->st_name);
1024 } else if (after) {
1025 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " 1003 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s "
1026 "before '%s' (at offset -0x%llx)\n", 1004 "in '%s'\n",
1027 modname, fromsec, (unsigned long long)r.r_offset, 1005 modname, fromsec, (unsigned long long)r.r_offset,
1028 secname, refsymname, 1006 secname, refsymname, elf->strtab + where->st_name);
1029 elf->strtab + after->st_name,
1030 (unsigned long long)r.r_offset);
1031 } else { 1007 } else {
1032 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n", 1008 warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n",
1033 modname, fromsec, (unsigned long long)r.r_offset, 1009 modname, fromsec, (unsigned long long)r.r_offset,