Bug 37280 - [4.4 Regression] weak symbol regression breaks linux kernel
Summary: [4.4 Regression] weak symbol regression breaks linux kernel
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.4.0
: P1 normal
Target Milestone: 4.4.0
Assignee: Hans-Peter Nilsson
URL:
Keywords: patch, wrong-code
Depends on: 37170
Blocks:
  Show dependency treegraph
 
Reported: 2008-08-29 15:12 UTC by Andi Kleen
Modified: 2008-09-22 02:12 UTC (History)
5 users (show)

See Also:
Host: x86_64-linux
Target: x86_64-linux
Build:
Known to work:
Known to fail:
Last reconfirmed: 2008-09-03 23:24:28


Attachments
preprocessed test case (88.30 KB, text/plain)
2008-08-29 16:02 UTC, Andi Kleen
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Andi Kleen 2008-08-29 15:12:18 UTC
The linux kernel doesn't build anymore with gcc version 4.4.0 20080826

The problem seems to be that one extern variable (kallsyms_token_index) declared with  __attribute__((weak)) does not get a ".weak" in the assembler output
anymore (compared the gcc 4.3)

I attached a preprocessed test case.

Build options:
-Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Os -m64 -mtune=generic -mno-red-zone -mcmodel=kernel -funit-at-a-time -maccumulate-outgoing-args -pipe -Wno-sign-compare -fno-asynchronous-unwind-tables -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -Iinclude/asm-x86/mach-default -Wframe-larger-than=2048 -fno-stack-protector -fomit-frame-pointer --param large-stack-frame=100 --param large-stack-frame-growth=100 -Wdeclaration-after-statement -Wno-pointer-sign -fverbose-asm
 
Built with gcc43:

% grep kallsyms_token_index kernel/kallsyms.s
 movzwl  kallsyms_token_index(%rax,%rax), %eax   # kallsyms_token_index, tmp118
        movzwl  kallsyms_token_index(%rax,%rax), %eax   # kallsyms_token_index, tmp124
        movzwl  kallsyms_token_index(%rax,%rax), %eax   # kallsyms_token_index, tmp105
        movzwl  kallsyms_token_index(%rax,%rax), %eax   # kallsyms_token_index, tmp102
        movzwl  kallsyms_token_index(%rax,%rax), %eax   # kallsyms_token_index, tmp106
        movzwl  kallsyms_token_index(%rax,%rax), %eax   # kallsyms_token_index, tmp93
        .weak   kallsyms_token_index


With 4.4:
  movzwl  kallsyms_token_index(%rdx,%rdx), %edx   # kallsyms_token_index, tmp116
        movzwl  kallsyms_token_index(%rdi,%rdi), %edi   # kallsyms_token_index, tmp122
        movzwl  kallsyms_token_index(%rdx,%rdx), %edx   # kallsyms_token_index, tmp103
        movzwl  kallsyms_token_index(%rdx,%rdx), %edx   # kallsyms_token_index, tmp100
        movzwl  kallsyms_token_index(%rcx,%rcx), %ecx   # kallsyms_token_index, tmp103
        movzwl  kallsyms_token_index(%rcx,%rcx), %ecx   # kallsyms_token_index, tmp91


Note no ".weak" in the second case. This breaks the build because it relies
on this symbol being weak on the first link pass.
Comment 1 Hans-Peter Nilsson 2008-08-29 16:02:04 UTC
(In reply to comment #0)
> I attached a preprocessed test case.

Where?
Comment 2 Andi Kleen 2008-08-29 16:02:04 UTC
Created attachment 16164 [details]
preprocessed test case
Comment 3 Hans-Peter Nilsson 2008-08-29 16:30:46 UTC
This is fixed by the patch in PR37170.
Comment 4 Hans-Peter Nilsson 2008-08-29 17:03:29 UTC
A wee bit shorter:
extern int kallsyms_token_index[] __attribute__((weak));
extern int kallsyms_token_table[] __attribute__((weak));
void kallsyms_expand_symbol(int *result)
{
  int len = *result;
  int *tptr;
  while(len) {
    tptr = &kallsyms_token_table[ kallsyms_token_index[*result] ];
    len--;
    while (*tptr) tptr++;
    *tptr = 1;
  }
 *result = 0;
}
Comment 5 happyarch 2008-09-03 22:58:34 UTC
Hi,

i tried your patch, but it doesn't work for my lfs64(linux from scratch pure-64bit)
http://gcc.gnu.org/ml/gcc-patches/2008-08/msg01407.html

...

  CC      init/version.o
  LD      init/built-in.o
  LD      .tmp_vmlinux1
kernel/built-in.o: In function `update_iter':
kallsyms.c:(.text+0x2fb86): undefined reference to `kallsyms_token_index'
kallsyms.c:(.text+0x2fbb5): undefined reference to `kallsyms_token_index'
kernel/built-in.o: In function `lookup_symbol_attrs':
(.text+0x2fdcc): undefined reference to `kallsyms_token_index'
kernel/built-in.o: In function `lookup_symbol_name':
(.text+0x2fea1): undefined reference to `kallsyms_token_index'
kernel/built-in.o: In function `kallsyms_lookup':
(.text+0x2ff92): undefined reference to `kallsyms_token_index'
kernel/built-in.o:(.text+0x30171): more undefined references to `kallsyms_token_index' follow
make: *** [.tmp_vmlinux1] Error 1
bash-3.2$ cc -v
Using built-in specs.
Target: x86_64-unknown-linux-gnu
Configured with: ../gcc/configure --prefix=/usr --libexecdir=/usr/lib --enable-shared --enable-threads=posix --enable-__cxa_atexit --enable-clocale=gnu --enable-languages=c,c++ --enable-static --disable-multilib
Thread model: posix
gcc version 4.4.0 20080903 (experimental) (GCC) 
bash-3.2$ pwd
/usr/src/linux-2.6.27-rc5


TIA
Comment 6 Hans-Peter Nilsson 2008-09-03 23:24:28 UTC
(In reply to comment #5)
> Hi,
> 
> i tried your patch, but it doesn't work for my lfs64(linux from scratch
> pure-64bit)
> http://gcc.gnu.org/ml/gcc-patches/2008-08/msg01407.html

You're a few versions behind.  This is the current one.  See also PR in the "depended on" box, PR37170:
<http://gcc.gnu.org/ml/gcc-patches/2008-09/msg00195.html>
Comment 7 happyarch 2008-09-04 23:07:34 UTC
(In reply to comment #6)
> (In reply to comment #5)
> > Hi,
> > 
> > i tried your patch, but it doesn't work for my lfs64(linux from scratch
> > pure-64bit)
> > http://gcc.gnu.org/ml/gcc-patches/2008-08/msg01407.html
> 
> You're a few versions behind.  This is the current one.  See also PR in the
> "depended on" box, PR37170:
> <http://gcc.gnu.org/ml/gcc-patches/2008-09/msg00195.html>
> 

Thanks it works like charm!
Comment 8 chaoyingfu@gcc.gnu.org 2008-09-16 01:11:49 UTC
Hi,

  For MIPS targets (mipsisa32r2-sde-elf), ".weak" is still not emitted.
  Thanks!

Ex:
# cat 152.c
extern int arr[] __attribute__((weak));

int test(int i)
{
  return arr[i];
}

# ~/dev/binutils3/build-all2/gcc/cc1 -quiet 152.c -o 152.s -O2
# cat 152.s
        .file   1 "152.c"
        .section .mdebug.abi32
        .previous
        .gnu_attribute 4, 1
        .text
        .align  2
        .globl  test
        .set    nomips16
        .ent    test
        .type   test, @function
test:
        .frame  $sp,0,$31               # vars= 0, regs= 0/0, args= 0, gp= 0
        .mask   0x00000000,0
        .fmask  0x00000000,0
        .set    noreorder
        .set    nomacro

        lui     $2,%hi(arr)
        addiu   $2,$2,%lo(arr)
        sll     $4,$4,2
        addu    $4,$4,$2
        j       $31
        lw      $2,0($4)

        .set    macro
        .set    reorder
        .end    test
        .size   test, .-test
        .ident  "GCC: (GNU) 4.4.0 20080915 (experimental) [trunk revision 131984]"
Comment 9 chaoyingfu@gcc.gnu.org 2008-09-16 18:54:32 UTC
Hi,

  I tried the following patch.
http://gcc.gnu.org/ml/gcc-patches/2008-09/msg00195.html

  ".weak symbol" can be emitted, but with two same lines.  Thanks!

Ex:
        .file   1 "152.c"
        .section .mdebug.abi32
        .previous
        .gnu_attribute 4, 1
        .text
        .align  2
        .globl  test
        .set    nomips16
        .ent    test
        .type   test, @function
test:
        .frame  $sp,0,$31               # vars= 0, regs= 0/0, args= 0, gp= 0
        .mask   0x00000000,0
        .fmask  0x00000000,0
        .set    noreorder
        .set    nomacro

        lui     $2,%hi(arr)
        addiu   $2,$2,%lo(arr)
        sll     $4,$4,2
        addu    $4,$4,$2
        j       $31
        lw      $2,0($4)

        .set    macro
        .set    reorder
        .end    test
        .size   test, .-test
        .weak   arr
        .weak   arr
        .ident  "GCC: (GNU) 4.4.0 20080915 (experimental) [trunk revision 131984
]"
Comment 10 Bernhard Reutner-Fischer 2008-09-16 19:15:49 UTC
(In reply to comment #9)
> Hi,
> 
>   I tried the following patch.
> http://gcc.gnu.org/ml/gcc-patches/2008-09/msg00195.html
> 
>   ".weak symbol" can be emitted, but with two same lines.  Thanks!

So that would bring you into the same situation as PR31537 is in (FE emits duplicate asm directives, quick workaround in the BE for weakrefs is attached to PR31537).
Comment 11 Hans-Peter Nilsson 2008-09-22 01:55:32 UTC
Subject: Bug 37280

Author: hp
Date: Mon Sep 22 01:54:03 2008
New Revision: 140539

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=140539
Log:
	PR middle-end/37170
	PR middle-end/37280
	* final.c (mark_symbol_ref_as_used): New helper function.
	(output_operand): Instead of just looking inside MEMs for
	SYMBOL_REFs, use new helper function and for_each_rtx.
	* varasm.c (assemble_external): Move #ifndef ASM_OUTPUT_EXTERNAL
	to after weak-handling.  Don't mark decls with TREE_STATIC as weak.
	Make head comment more general.
	* config/darwin.c (machopic_output_indirection): Handle weak
	references here, like in assemble_external.

Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/config/darwin.c
    trunk/gcc/final.c
    trunk/gcc/varasm.c

Comment 12 Hans-Peter Nilsson 2008-09-22 01:56:05 UTC
Subject: Bug 37280

Author: hp
Date: Mon Sep 22 01:54:41 2008
New Revision: 140540

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=140540
Log:
	PR middle-end/37170
	PR middle-end/37280
	* gcc.dg/weak/weak-15.c, gcc.dg/weak/weak-16.c,
	g++.dg/ext/inline1.C: New tests.

Added:
    trunk/gcc/testsuite/g++.dg/ext/inline1.C
    trunk/gcc/testsuite/gcc.dg/weak/weak-15.c
    trunk/gcc/testsuite/gcc.dg/weak/weak-16.c
Modified:
    trunk/gcc/testsuite/ChangeLog

Comment 13 Hans-Peter Nilsson 2008-09-22 02:12:23 UTC
(In reply to comment #10)
> (In reply to comment #9)
> >   ".weak symbol" can be emitted, but with two same lines.  Thanks!
> So that would bring you into the same situation as PR31537 is in (FE emits
> duplicate asm directives, quick workaround in the BE for weakrefs is attached
> to PR31537).

Pre-existing wart.
Better use a hashtable than a linked list (i.e. tree) for weak_decls.
I suggest opening a separate PR for that; this one's now FIXED.