x86/kbuild: enable modversions for symbols exported from asm
diff mbox

Message ID 14455987.OWjnZpEEup@wuerfel
State New
Headers show

Commit Message

Arnd Bergmann Dec. 2, 2016, 10:55 a.m. UTC
On Thursday, December 1, 2016 10:26:07 AM CET Linus Torvalds wrote:
> On Thu, Dec 1, 2016 at 5:58 AM, Arnd Bergmann <arnd@arndb.de> wrote:
> >
> > WARNING: EXPORT symbol "mcount" [arch/x86/entry/built-in.ko] version generation failed, symbol will not be versioned.
> > WARNING: EXPORT symbol "mcount" [arch/x86/built-in.ko] version generation failed, symbol will not be versioned.
> > WARNING: EXPORT symbol "cmpxchg8b_emu" [vmlinux] version generation failed, symbol will not be versioned.
> > WARNING: EXPORT symbol "empty_zero_page" [vmlinux] version generation failed, symbol will not be versioned.
> > WARNING: EXPORT symbol "mcount" [vmlinux] version generation failed, symbol will not be versioned.
> > WARNING: EXPORT symbol "cmpxchg8b_emu" [vmlinux] version generation failed, symbol will not be versioned.
> > WARNING: EXPORT symbol "empty_zero_page" [vmlinux] version generation failed, symbol will not be versioned.
> > WARNING: EXPORT symbol "mcount" [vmlinux] version generation failed, symbol will not be versioned.
> >
> > Out of 12 randconfig builds that had CONFIG_MODVERSIONS enabled, all 12
> > had this problem, though not always with all the symbols.
> 
> Well, the good news is that pretty fundamentally, if it's just the asm
> symbls, those really don't have ABI's that change (or if they change,
> it's such a fundamental change that everything else will likely have
> changed too and we don't need to worry about one asm symbol crc - the
> change will be caught by other symbols).

Yes, it's always been just the assembly symbols that broke, these were
the ones that Al's original patch changed and that ended up with
no version information.

> So I think the whole "we don't really care" approach should work fine.
> The "let's make every symbol always be versioned" may just be too much
> pain for no real gain.

I have managed to bisect the link failure to a specific binutils
commit by Alan Modra now:

d983c8c ("Strip undefined symbols from .symtab")

went into binutils-2_26 and was reverted in 

a82e3ef ("Revert "Strip undefined symbols from .symtab"")

after the release branch for 2.26 was started, so that version
ended up being fine. However, the 2.27 version never saw the revert
and causes loadable kernel modules to become unusable when they refer
to a weak symbol in vmlinux. This works with 2.26 and lower:

$ nm obj-arm/vmlinux | grep __gnu_mcount_nc
         w __crc___gnu_mcount_nc
c031ed58 T __gnu_mcount_nc
c0ef4590 r __kcrctab___gnu_mcount_nc
c0efb4f5 r __kstrtab___gnu_mcount_nc
c0ee68bc R __ksymtab___gnu_mcount_nc

and this is breaks with 2.27 and higher:
$ make modules 2>&1 | tail -n 1
WARNING: "__gnu_mcount_nc" [drivers/ata/ahci_platform.ko] has no CRC!

$ nm obj-arm/vmlinux | grep __gnu_mcount_nc
c031ed58 T __gnu_mcount_nc
c0ef4590 r __kcrctab___gnu_mcount_nc
c0efb4f5 r __kstrtab___gnu_mcount_nc
c0ee68bc R __ksymtab___gnu_mcount_nc

Applying the patch below on top of today's binutils master branch
makes it work again. The real patch will also have to fix the testsuite.

	Arnd

---
commit 9a48071533f311ff1f567361874fab141bd77230
Author: Arnd Bergmann <arnd@arndb.de>
Date:   Fri Dec 2 11:31:34 2016 +0100

    Revert "Strip undefined symbols from .symtab"
    
    This reverts commit d983c8c5503d680c6d4955ceb610a9beebc64460.
    
    Signed-off-by: Arnd Bergmann <arnd@arndb.de>


--
To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Linus Torvalds Dec. 2, 2016, 5:04 p.m. UTC | #1
On Fri, Dec 2, 2016 at 2:55 AM, Arnd Bergmann <arnd@arndb.de> wrote:
>
> Yes, it's always been just the assembly symbols that broke, these were
> the ones that Al's original patch changed and that ended up with
> no version information.

Ok, and the reason is because even if we have a weak symbol from C, it
would always have a value.

Good to know what the heck the problem was.

> I have managed to bisect the link failure to a specific binutils
> commit by Alan Modra now:

Thanks. And I committed your "set to zero" patch, so we can hopefully
leave this all behind us.

I marked it for stable (not because older kernels need it, but because
it's the right thing to do and if we ever backport anything that
causes this we don't want to forget this).

And I'll keep the workaround in kernel/module.c just because it's
really late in the rc series, and I'd rather have both belt and
suspenders for this all right now.

               Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Alan Modra Dec. 4, 2016, 7:44 a.m. UTC | #2
On Fri, Dec 02, 2016 at 11:55:58AM +0100, Arnd Bergmann wrote:
> I have managed to bisect the link failure to a specific binutils
> commit by Alan Modra now:
> 
> d983c8c ("Strip undefined symbols from .symtab")
> 
> went into binutils-2_26 and was reverted in 
> 
> a82e3ef ("Revert "Strip undefined symbols from .symtab"")
> 
> after the release branch for 2.26 was started, so that version
> ended up being fine. However, the 2.27 version never saw the revert
> and causes loadable kernel modules to become unusable when they refer
> to a weak symbol in vmlinux. This works with 2.26 and lower:

See https://sourceware.org/ml/binutils/2016-01/msg00118.html thread
for discussion on why the patch was reverted for 2.26.  At the time I
believed that only the ppc64 kernel was affected, by a weak undefined
"__crc_TOC." disappearing.  Am I correct in thinking that remained
true up until Linus' merge commit 84d69848c9 2016-10-14?

As far as reverting the binutils commit goes, I'm quite willing to do
that if necessary.  You can see how important I think the fix was by
viewing https://sourceware.org/bugzilla/show_bug.cgi?id=4317 and
noticing that the bug was reported in 2007 and didn't see any action
for 8 years..
Linus Torvalds Dec. 4, 2016, 8:44 p.m. UTC | #3
On Sat, Dec 3, 2016 at 11:44 PM, Alan Modra <amodra@gmail.com> wrote:
>
> As far as reverting the binutils commit goes, I'm quite willing to do
> that if necessary

I think we have the proper fix in the kernel now, witht he "mark weak
asm symbols with value 0". Or if not "proper", then at least
acceptable. So I think the ship has sailed on the binutils change, and
there's no point in reverting it any more.

          Linus
--
To unsubscribe from this list: send the line "unsubscribe linux-kbuild" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Patch
diff mbox

diff --git a/bfd/elflink.c b/bfd/elflink.c
index 5f87f87..57c4d42 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -9354,9 +9354,8 @@  elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
      a regular file, or that we have been told to strip.  However, if
      h->indx is set to -2, the symbol is used by a reloc and we must
      output it.  */
-  strip = FALSE;
   if (h->indx == -2)
-    ;
+    strip = FALSE;
   else if ((h->def_dynamic
 	    || h->ref_dynamic
 	    || h->root.type == bfd_link_hash_new)
@@ -9382,13 +9381,14 @@  elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
 	   && h->root.u.undef.abfd != NULL
 	   && (h->root.u.undef.abfd->flags & BFD_PLUGIN) != 0)
     strip = TRUE;
+  else
+    strip = FALSE;
 
   type = h->type;
 
   /* If we're stripping it, and it's not a dynamic symbol, there's
-     nothing else to do.   However, if it is a forced local symbol or
-     an ifunc symbol we need to give the backend finish_dynamic_symbol
-     function a chance to make it dynamic.  */
+     nothing else to do unless it is a forced local symbol or a
+     STT_GNU_IFUNC symbol.  */
   if (strip
       && h->dynindx == -1
       && type != STT_GNU_IFUNC
@@ -9691,18 +9691,9 @@  elf_link_output_extsym (struct bfd_hash_entry *bh, void *data)
 	}
     }
 
-  /* If the symbol is undefined, and we didn't output it to .dynsym,
-     strip it from .symtab too.  Obviously we can't do this for
-     relocatable output or when needed for --emit-relocs.  */
-  else if (input_sec == bfd_und_section_ptr
-	   && h->indx != -2
-	   && !bfd_link_relocatable (flinfo->info))
-    return TRUE;
-  /* Also strip others that we couldn't earlier due to dynamic symbol
-     processing.  */
-  if (strip)
-    return TRUE;
-  if ((input_sec->flags & SEC_EXCLUDE) != 0)
+  /* If we're stripping it, then it was just a dynamic symbol, and
+     there's nothing else to do.  */
+  if (strip || (input_sec->flags & SEC_EXCLUDE) != 0)
     return TRUE;
 
   /* Output a FILE symbol so that following locals are not associated
@@ -9952,9 +9943,8 @@  elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
 
       *ppsection = isec;
 
-      /* Don't output the first, undefined, symbol.  In fact, don't
-	 output any undefined local symbol.  */
-      if (isec == bfd_und_section_ptr)
+      /* Don't output the first, undefined, symbol.  */
+      if (ppsection == flinfo->sections)
 	continue;
 
       if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)