NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

toolchain/45985: test lib/libc/tls/t_tls_dynamic failed on 32-bit sparc



>Number:         45985
>Category:       toolchain
>Synopsis:       test lib/libc/tls/t_tls_dynamic failed on 32-bit sparc
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    toolchain-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Feb 11 18:25:00 +0000 2012
>Originator:     Takeshi Nakayama
>Release:        NetBSD 5.99.64
>Organization:
>Environment:
System: NetBSD gaia 5.99.64 NetBSD 5.99.64 (GENERIC32.UP) #6: Sat Feb 11 
06:38:56 JST 2012 
takeshi@nyx:/export/netbsd-cvs/src/sys/arch/sparc64/compile/GENERIC32.UP sparc
Architecture: sparc
Machine: sparc  

>Description:
        test lib/libc/tls/t_tls_dynamic failed on 32-bit sparc as follows:

tp-start: 1328678328.27258, lib/libc/tls/t_tls_dynamic, 1
tc-start: 1328678328.28234, t_tls_dynamic
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:68: var1 != 
1
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:69: var2 != 0
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:71: var1 != 
2
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:72: var2 != 
2
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:74: var1 != 
3
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:75: var2 != 
3
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:78: 
dso_var1 != getpid
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:68: var1 != 
1
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:69: var2 != 0
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:71: var1 != 
2
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:72: var2 != 
2
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:74: var1 != 
3
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:75: var2 != 
3
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:78: 
dso_var1 != getpid
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:68: var1 != 
1
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:69: var2 != 0
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:71: var1 != 
2
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:72: var2 != 
2
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:74: var1 != 
3
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:75: var2 != 
3
tc-se:*** Check failed: /usr/src/tests/lib/libc/tls/t_tls_dynamic.c:78: 
dso_var1 != getpid
tc-end: 1328678328.67452, t_tls_dynamic, failed, 21 checks failed; see output 
for more details
tp-end: 1328678328.68459, lib/libc/tls/t_tls_dynamic

>How-To-Repeat:
        cd /usr/tests/lib/libc/tls && atf-run t_tls_dynamic

>Fix:
        Our in-tree gcc generates the code as bellow, and gas makes
        non PC-relative relocations R_SPARC_HI22 and R_SPARC_LO10
        for _GLOBAL_OFFSET_TABLE since it is in non-PIC mode.

testf:
        save    %sp, -96, %sp
        st      %i0, [%fp+68]
        sethi   %hi(_GLOBAL_OFFSET_TABLE_-8), %l7
        add     %l7, %lo(_GLOBAL_OFFSET_TABLE_-4), %l7
        call    __sparc_get_pc_thunk.l7
         nop
        sethi   %tie_hi22(var1), %g1
        add     %g1, %tie_lo10(var1), %g1
        ld      [%l7 + %g1], %g1, %tie_ld(var1)
        add     %g7, %g1, %g1, %tie_add(var1)
        ld      [%g1], %g1
        cmp     %g1, 1


        It seemes that this code is generated around at the 3215
        line in src/external/gpl3/gcc/dist/gcc/config/sparc/sparc.c.

/* Return the Global Offset Table to be used in TLS mode.  */

static rtx
sparc_tls_got (void)
{
  /* In PIC mode, this is just the PIC offset table.  */
  if (flag_pic)
    {
      crtl->uses_pic_offset_table = 1;
      return pic_offset_table_rtx;
    }

  /* In non-PIC mode, Sun as (unlike GNU as) emits PC-relative relocations for
     the GOT symbol with the 32-bit ABI, so we reload the GOT register.  */
  if (TARGET_SUN_TLS && TARGET_ARCH32)
    {
      load_got_register ();
      return global_offset_table_rtx;
    }

  /* In all other cases, we load a new pseudo with the GOT symbol.  */
  return copy_to_reg (sparc_got ());
}


        So applying the folowing patch will fix the problem since
        we use gas.

Index: netbsd-elf.h
===================================================================
RCS file: /cvsroot/src/external/gpl3/gcc/dist/gcc/config/sparc/netbsd-elf.h,v
retrieving revision 1.3
diff -u -d -r1.3 netbsd-elf.h
--- netbsd-elf.h        1 Jul 2011 01:24:04 -0000       1.3
+++ netbsd-elf.h        11 Feb 2012 08:13:17 -0000
@@ -266,6 +266,13 @@
 
 #endif /* SPARC_BI_ARCH */
 
+#ifdef HAVE_AS_TLS
+#undef TARGET_SUN_TLS
+#undef TARGET_GNU_TLS
+#define TARGET_SUN_TLS 0
+#define TARGET_GNU_TLS 1
+#endif
+
 /* We use GNU ld so undefine this so that attribute((init_priority)) works.  */
 #undef CTORS_SECTION_ASM_OP
 #undef DTORS_SECTION_ASM_OP


        FYI, FreeBSD has the same change in:
        http://svnweb.freebsd.org/base?view=revision&revision=219534

        With this patch, gcc generates the code as bellow, and pass
        the test.

testf:
        save    %sp, -96, %sp
        st      %i0, [%fp+68]
        sethi   %hi(_GLOBAL_OFFSET_TABLE_), %g1
        or      %g1, %lo(_GLOBAL_OFFSET_TABLE_), %g1
        sethi   %tie_hi22(var1), %g2
        add     %g2, %tie_lo10(var1), %g2
        ld      [%g1 + %g2], %g1, %tie_ld(var1)
        ld      [%g7+%g1], %g1
        cmp     %g1, 1



Home | Main Index | Thread Index | Old Index