Skip to content

Commit e241a63

Browse files
committed
kbuild: warn about ld added unique sections
If there is a mixture of specifying sections for code in gcc and assembler then if the assembler code do not add the "ax" flags the linker will see this as two different sections and generate unique sections for each. ld does so by adding a dot and a number. Teach modpost to warn if a section shows up that match this pattern - but do this only for non-debug sections. It will result in warnings like this: WARNING: vmlinux.o (.sched.text.1): unexpected section name. The (.[number]+) following section name are ld generated and not expected. Did you forget to use "ax"/"aw" in a .S file? Note that for example <linux/init.h> contains section definitions for use in .S files. All warnings seen with a defconfig build for: x86 (32+64bit) and sparc64 has been fixed (via respective maintainers). arm, powerpc (64 bit), s390 (32 bit), ia64, alpha, sh4 checked - no warnings seen with a defconfig build. Signed-off-by: Sam Ravnborg <[email protected]>
1 parent 588ccd7 commit e241a63

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

scripts/mod/modpost.c

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,43 @@ int match(const char *sym, const char * const pat[])
696696
static const char *section_white_list[] =
697697
{ ".debug*", ".stab*", ".note*", ".got*", ".toc*", NULL };
698698

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+
699736
#define ALL_INIT_DATA_SECTIONS \
700737
".init.data$", ".devinit.data$", ".cpuinit.data$", ".meminit.data$"
701738
#define ALL_EXIT_DATA_SECTIONS \
@@ -1311,8 +1348,9 @@ static void section_rela(const char *modname, struct elf_info *elf,
13111348
fromsec = sech_name(elf, sechdr);
13121349
fromsec += strlen(".rela");
13131350
/* if from section (name) is know good then skip it */
1314-
if (match(fromsec, section_white_list))
1351+
if (check_section(modname, fromsec))
13151352
return;
1353+
13161354
for (rela = start; rela < stop; rela++) {
13171355
r.r_offset = TO_NATIVE(rela->r_offset);
13181356
#if KERNEL_ELFCLASS == ELFCLASS64
@@ -1354,7 +1392,7 @@ static void section_rel(const char *modname, struct elf_info *elf,
13541392
fromsec = sech_name(elf, sechdr);
13551393
fromsec += strlen(".rel");
13561394
/* if from section (name) is know good then skip it */
1357-
if (match(fromsec, section_white_list))
1395+
if (check_section(modname, fromsec))
13581396
return;
13591397

13601398
for (rel = start; rel < stop; rel++) {

0 commit comments

Comments
 (0)