diff options
-rw-r--r-- | scripts/mod/modpost.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 3cf1ba8220d2..f8efc93eb700 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -696,6 +696,43 @@ int match(const char *sym, const char * const pat[]) | |||
696 | static const char *section_white_list[] = | 696 | static const char *section_white_list[] = |
697 | { ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL }; | 697 | { ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL }; |
698 | 698 | ||
699 | /* | ||
700 | * Is this section one we do not want to check? | ||
701 | * This is often debug sections. | ||
702 | * If we are going to check this section then | ||
703 | * test if section name ends with a dot and a number. | ||
704 | * This is used to find sections where the linker have | ||
705 | * appended a dot-number to make the name unique. | ||
706 | * The cause of this is often a section specified in assembler | ||
707 | * without "ax" / "aw" and the same section used in .c | ||
708 | * code where gcc add these. | ||
709 | */ | ||
710 | static int check_section(const char *modname, const char *sec) | ||
711 | { | ||
712 | const char *e = sec + strlen(sec) - 1; | ||
713 | if (match(sec, section_white_list)) | ||
714 | return 1; | ||
715 | |||
716 | if (*e && isdigit(*e)) { | ||
717 | /* consume all digits */ | ||
718 | while (*e && e != sec && isdigit(*e)) | ||
719 | e--; | ||
720 | if (*e == '.') { | ||
721 | warn("%s (%s): unexpected section name.\n" | ||
722 | "The (.[number]+) following section name are " | ||
723 | "ld generated and not expected.\n" | ||
724 | "Did you forget to use \"ax\"/\"aw\" " | ||
725 | "in a .S file?\n" | ||
726 | "Note that for example <linux/init.h> contains\n" | ||
727 | "section definitions for use in .S files.\n\n", | ||
728 | modname, sec); | ||
729 | } | ||
730 | } | ||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | |||
735 | |||
699 | #define ALL_INIT_DATA_SECTIONS \ | 736 | #define ALL_INIT_DATA_SECTIONS \ |
700 | ".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$" | 737 | ".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$" |
701 | #define ALL_EXIT_DATA_SECTIONS \ | 738 | #define ALL_EXIT_DATA_SECTIONS \ |
@@ -1311,8 +1348,9 @@ static void section_rela(const char *modname, struct elf_info *elf, | |||
1311 | fromsec = sech_name(elf, sechdr); | 1348 | fromsec = sech_name(elf, sechdr); |
1312 | fromsec += strlen(".rela"); | 1349 | fromsec += strlen(".rela"); |
1313 | /* if from section (name) is know good then skip it */ | 1350 | /* if from section (name) is know good then skip it */ |
1314 | if (match(fromsec, section_white_list)) | 1351 | if (check_section(modname, fromsec)) |
1315 | return; | 1352 | return; |
1353 | |||
1316 | for (rela = start; rela < stop; rela++) { | 1354 | for (rela = start; rela < stop; rela++) { |
1317 | r.r_offset = TO_NATIVE(rela->r_offset); | 1355 | r.r_offset = TO_NATIVE(rela->r_offset); |
1318 | #if KERNEL_ELFCLASS == ELFCLASS64 | 1356 | #if KERNEL_ELFCLASS == ELFCLASS64 |
@@ -1354,7 +1392,7 @@ static void section_rel(const char *modname, struct elf_info *elf, | |||
1354 | fromsec = sech_name(elf, sechdr); | 1392 | fromsec = sech_name(elf, sechdr); |
1355 | fromsec += strlen(".rel"); | 1393 | fromsec += strlen(".rel"); |
1356 | /* if from section (name) is know good then skip it */ | 1394 | /* if from section (name) is know good then skip it */ |
1357 | if (match(fromsec, section_white_list)) | 1395 | if (check_section(modname, fromsec)) |
1358 | return; | 1396 | return; |
1359 | 1397 | ||
1360 | for (rel = start; rel < stop; rel++) { | 1398 | for (rel = start; rel < stop; rel++) { |