diff options
| author | Sam Ravnborg <sam@ravnborg.org> | 2008-01-23 15:13:50 -0500 |
|---|---|---|
| committer | Sam Ravnborg <sam@ravnborg.org> | 2008-01-28 17:21:18 -0500 |
| commit | 58fb0d4f2fd5773ec0158d1f2774dca6a03e6984 (patch) | |
| tree | 0590916cf6ec3daa40be925bcb4ebc81316e64c6 /scripts/mod/modpost.c | |
| parent | ff13f92690249061311c7cf69a89e5a2fb068811 (diff) | |
kbuild: simplified warning report in modpost
Refactor code so the warning report function
does nothing else than reporting warnings.
As a side effect some other code paths were cleaned
up by this.
Signed-off-by: Sam Ravnborg <sam@ravnborg.org>
Diffstat (limited to 'scripts/mod/modpost.c')
| -rw-r--r-- | scripts/mod/modpost.c | 104 |
1 files changed, 52 insertions, 52 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index e4099cd5f085..0a80acafd212 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
| @@ -607,7 +607,10 @@ static int strrcmp(const char *s, const char *sub) | |||
| 607 | 607 | ||
| 608 | static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) | 608 | static const char *sym_name(struct elf_info *elf, Elf_Sym *sym) |
| 609 | { | 609 | { |
| 610 | return elf->strtab + sym->st_name; | 610 | if (sym) |
| 611 | return elf->strtab + sym->st_name; | ||
| 612 | else | ||
| 613 | return ""; | ||
| 611 | } | 614 | } |
| 612 | 615 | ||
| 613 | static const char *sec_name(struct elf_info *elf, int shndx) | 616 | static const char *sec_name(struct elf_info *elf, int shndx) |
| @@ -812,7 +815,6 @@ static int section_mismatch(const char *fromsec, const char *tosec) | |||
| 812 | return 0; | 815 | return 0; |
| 813 | } | 816 | } |
| 814 | 817 | ||
| 815 | |||
| 816 | /** | 818 | /** |
| 817 | * Whitelist to allow certain references to pass with no warning. | 819 | * Whitelist to allow certain references to pass with no warning. |
| 818 | * | 820 | * |
| @@ -856,36 +858,35 @@ static int section_mismatch(const char *fromsec, const char *tosec) | |||
| 856 | * refsymname = __init_begin, _sinittext, _einittext | 858 | * refsymname = __init_begin, _sinittext, _einittext |
| 857 | * | 859 | * |
| 858 | **/ | 860 | **/ |
| 859 | static int secref_whitelist(const char *modname, const char *tosec, | 861 | static int secref_whitelist(const char *fromsec, const char *fromsym, |
| 860 | const char *fromsec, const char *atsym, | 862 | const char *tosec, const char *tosym) |
| 861 | const char *refsymname) | ||
| 862 | { | 863 | { |
| 863 | /* Check for pattern 0 */ | 864 | /* Check for pattern 0 */ |
| 864 | if (match(fromsec, initref_sections)) | 865 | if (match(fromsec, initref_sections)) |
| 865 | return 1; | 866 | return 0; |
| 866 | 867 | ||
| 867 | /* Check for pattern 1 */ | 868 | /* Check for pattern 1 */ |
| 868 | if (match(tosec, init_data_sections) && | 869 | if (match(tosec, init_data_sections) && |
| 869 | match(fromsec, data_sections) && | 870 | match(fromsec, data_sections) && |
| 870 | (strncmp(atsym, "__param", strlen("__param")) == 0)) | 871 | (strncmp(fromsym, "__param", strlen("__param")) == 0)) |
| 871 | return 1; | 872 | return 0; |
| 872 | 873 | ||
| 873 | /* Check for pattern 2 */ | 874 | /* Check for pattern 2 */ |
| 874 | if (match(tosec, init_exit_sections) && | 875 | if (match(tosec, init_exit_sections) && |
| 875 | match(fromsec, data_sections) && | 876 | match(fromsec, data_sections) && |
| 876 | match(atsym, symbol_white_list)) | 877 | match(fromsym, symbol_white_list)) |
| 877 | return 1; | 878 | return 0; |
| 878 | 879 | ||
| 879 | /* Check for pattern 3 */ | 880 | /* Check for pattern 3 */ |
| 880 | if (match(fromsec, head_sections) && | 881 | if (match(fromsec, head_sections) && |
| 881 | match(tosec, init_sections)) | 882 | match(tosec, init_sections)) |
| 882 | return 1; | 883 | return 0; |
| 883 | 884 | ||
| 884 | /* Check for pattern 4 */ | 885 | /* Check for pattern 4 */ |
| 885 | if (match(refsymname, linker_symbols)) | 886 | if (match(tosym, linker_symbols)) |
| 886 | return 1; | 887 | return 0; |
| 887 | 888 | ||
| 888 | return 0; | 889 | return 1; |
| 889 | } | 890 | } |
| 890 | 891 | ||
| 891 | /** | 892 | /** |
| @@ -987,41 +988,49 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr, | |||
| 987 | return near; | 988 | return near; |
| 988 | } | 989 | } |
| 989 | 990 | ||
| 990 | /** | 991 | /* |
| 991 | * Print a warning about a section mismatch. | 992 | * Print a warning about a section mismatch. |
| 992 | * Try to find symbols near it so user can find it. | 993 | * Try to find symbols near it so user can find it. |
| 993 | * Check whitelist before warning - it may be a false positive. | 994 | * Check whitelist before warning - it may be a false positive. |
| 994 | **/ | 995 | */ |
| 995 | static void warn_sec_mismatch(const char *modname, const char *fromsec, | 996 | static void report_sec_mismatch(const char *modname, |
| 996 | struct elf_info *elf, Elf_Sym *sym, Elf_Rela r) | 997 | const char *fromsec, |
| 998 | unsigned long long fromaddr, | ||
| 999 | const char *fromsym, | ||
| 1000 | const char *tosec, const char *tosym) | ||
| 997 | { | 1001 | { |
| 998 | Elf_Sym *where; | 1002 | if (strlen(tosym)) { |
| 999 | Elf_Sym *refsym; | ||
| 1000 | const char *refsymname = ""; | ||
| 1001 | const char *secname; | ||
| 1002 | |||
| 1003 | secname = sec_name(elf, sym->st_shndx); | ||
| 1004 | where = find_elf_symbol2(elf, r.r_offset, fromsec); | ||
| 1005 | |||
| 1006 | refsym = find_elf_symbol(elf, r.r_addend, sym); | ||
| 1007 | if (refsym && strlen(sym_name(elf, refsym))) | ||
| 1008 | refsymname = sym_name(elf, refsym); | ||
| 1009 | |||
| 1010 | /* check whitelist - we may ignore it */ | ||
| 1011 | if (secref_whitelist(modname, secname, fromsec, | ||
| 1012 | where ? sym_name(elf, where) : "", | ||
| 1013 | refsymname)) | ||
| 1014 | return; | ||
| 1015 | |||
| 1016 | if (where) { | ||
| 1017 | warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " | 1003 | warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s " |
| 1018 | "in '%s'\n", | 1004 | "in '%s'\n", |
| 1019 | modname, fromsec, (unsigned long long)r.r_offset, | 1005 | modname, fromsec, fromaddr, |
| 1020 | secname, refsymname, sym_name(elf, where)); | 1006 | tosec, tosym, fromsym); |
| 1021 | } else { | 1007 | } else { |
| 1022 | 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", |
| 1023 | modname, fromsec, (unsigned long long)r.r_offset, | 1009 | modname, fromsec, fromaddr, |
| 1024 | secname, refsymname); | 1010 | tosec, tosym); |
| 1011 | } | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | static void check_section_mismatch(const char *modname, struct elf_info *elf, | ||
| 1015 | Elf_Rela *r, Elf_Sym *sym, const char *fromsec) | ||
| 1016 | { | ||
| 1017 | const char *tosec; | ||
| 1018 | |||
| 1019 | tosec = sec_name(elf, sym->st_shndx); | ||
| 1020 | if (section_mismatch(fromsec, tosec)) { | ||
| 1021 | const char *fromsym; | ||
| 1022 | const char *tosym; | ||
| 1023 | |||
| 1024 | fromsym = sym_name(elf, | ||
| 1025 | find_elf_symbol2(elf, r->r_offset, fromsec)); | ||
| 1026 | tosym = sym_name(elf, | ||
| 1027 | find_elf_symbol(elf, r->r_addend, sym)); | ||
| 1028 | |||
| 1029 | /* check whitelist - we may ignore it */ | ||
| 1030 | if (secref_whitelist(fromsec, fromsym, tosec, tosym)) { | ||
| 1031 | report_sec_mismatch(modname, fromsec, r->r_offset, | ||
| 1032 | fromsym, tosec, tosym); | ||
| 1033 | } | ||
| 1025 | } | 1034 | } |
| 1026 | } | 1035 | } |
| 1027 | 1036 | ||
| @@ -1107,7 +1116,6 @@ static void section_rela(const char *modname, struct elf_info *elf, | |||
| 1107 | Elf_Rela r; | 1116 | Elf_Rela r; |
| 1108 | unsigned int r_sym; | 1117 | unsigned int r_sym; |
| 1109 | const char *fromsec; | 1118 | const char *fromsec; |
| 1110 | const char * tosec; | ||
| 1111 | 1119 | ||
| 1112 | Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset; | 1120 | Elf_Rela *start = (void *)elf->hdr + sechdr->sh_offset; |
| 1113 | Elf_Rela *stop = (void *)start + sechdr->sh_size; | 1121 | Elf_Rela *stop = (void *)start + sechdr->sh_size; |
| @@ -1117,7 +1125,6 @@ static void section_rela(const char *modname, struct elf_info *elf, | |||
| 1117 | /* if from section (name) is know good then skip it */ | 1125 | /* if from section (name) is know good then skip it */ |
| 1118 | if (match(fromsec, section_white_list)) | 1126 | if (match(fromsec, section_white_list)) |
| 1119 | return; | 1127 | return; |
| 1120 | |||
| 1121 | for (rela = start; rela < stop; rela++) { | 1128 | for (rela = start; rela < stop; rela++) { |
| 1122 | r.r_offset = TO_NATIVE(rela->r_offset); | 1129 | r.r_offset = TO_NATIVE(rela->r_offset); |
| 1123 | #if KERNEL_ELFCLASS == ELFCLASS64 | 1130 | #if KERNEL_ELFCLASS == ELFCLASS64 |
| @@ -1140,10 +1147,7 @@ static void section_rela(const char *modname, struct elf_info *elf, | |||
| 1140 | /* Skip special sections */ | 1147 | /* Skip special sections */ |
| 1141 | if (sym->st_shndx >= SHN_LORESERVE) | 1148 | if (sym->st_shndx >= SHN_LORESERVE) |
| 1142 | continue; | 1149 | continue; |
| 1143 | 1150 | check_section_mismatch(modname, elf, &r, sym, fromsec); | |
| 1144 | tosec = sec_name(elf, sym->st_shndx); | ||
| 1145 | if (section_mismatch(fromsec, tosec)) | ||
| 1146 | warn_sec_mismatch(modname, fromsec, elf, sym, r); | ||
| 1147 | } | 1151 | } |
| 1148 | } | 1152 | } |
| 1149 | 1153 | ||
| @@ -1155,7 +1159,6 @@ static void section_rel(const char *modname, struct elf_info *elf, | |||
| 1155 | Elf_Rela r; | 1159 | Elf_Rela r; |
| 1156 | unsigned int r_sym; | 1160 | unsigned int r_sym; |
| 1157 | const char *fromsec; | 1161 | const char *fromsec; |
| 1158 | const char * tosec; | ||
| 1159 | 1162 | ||
| 1160 | Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset; | 1163 | Elf_Rel *start = (void *)elf->hdr + sechdr->sh_offset; |
| 1161 | Elf_Rel *stop = (void *)start + sechdr->sh_size; | 1164 | Elf_Rel *stop = (void *)start + sechdr->sh_size; |
| @@ -1202,10 +1205,7 @@ static void section_rel(const char *modname, struct elf_info *elf, | |||
| 1202 | /* Skip special sections */ | 1205 | /* Skip special sections */ |
| 1203 | if (sym->st_shndx >= SHN_LORESERVE) | 1206 | if (sym->st_shndx >= SHN_LORESERVE) |
| 1204 | continue; | 1207 | continue; |
| 1205 | 1208 | check_section_mismatch(modname, elf, &r, sym, fromsec); | |
| 1206 | tosec = sec_name(elf, sym->st_shndx); | ||
| 1207 | if (section_mismatch(fromsec, tosec)) | ||
| 1208 | warn_sec_mismatch(modname, fromsec, elf, sym, r); | ||
| 1209 | } | 1209 | } |
| 1210 | } | 1210 | } |
| 1211 | 1211 | ||
