Bug is initially reported by Daniel Gurney as https://bugs.gentoo.org/737996. There the system is -mcpu=7450 (32-bit power7). The bug manifests as a hangup in __internal_atexit() for every binary linket with libc due to uninitialized memory in '__exit_funcs_lock' lock. """ backtrace: #0 0x6fe03c60 in __lll_lock_wait_private (futex=futex@entry=0x6ff4aea8 <__exit_funcs_lock>) at ./lowlevellock.c:35 #1 0x6fdb8e68 in __internal_atexit (func=0xb7be4a74 <_dl_fini>, arg=arg@entry=0x0, d=d@entry=0x0, listp=0x6ff4adec <__exit_funcs>) at cxa_atexit.c:43 #2 0x6fdb8ef0 in __GI___cxa_atexit (func=<optimized out>, arg=arg@entry=0x0, d=d@entry=0x0) at cxa_atexit.c:70 #3 0x6fd9cba4 in generic_start_main (main=0x6ffc1310, argc=1, argv=0xbfc5da80, auxvec=0xbfc5de34, init=0x6ffcc090, rtld_fini=<optimized out>, stack_end=<optimized out>, fini=<optimized out>) at ../csu/libc-start.c:240 #4 0x6fd9cdc8 in __libc_start_main (argc=<optimized out>, argv=<optimized out>, ev=<optimized out>, auxvec=<optimized out>, rtld_fini=<optimized out>, stinfo=<optimized out>, stack_on_entry=<optimized out>) at ../sysdeps/unix/sysv/linux/powerpc/libc-start.c:98 #5 0x00000000 in ?? () """ Working glibs was built as ../glibc/configure --host=powerpc-unknown-linux-gnu --prefix=/usr \ CC="powerpc-unknown-linux-gnu-gcc" \ CFLAGS="-O2 -ggdb3" Problematic glibc was built as: ../glibc/configure --host=powerpc-unknown-linux-gnu --prefix=/usr \ CC="powerpc-unknown-linux-gnu-gcc" \ CFLAGS="-O2 -ggdb3 -mcpu=7450" What works: in '-O2' mode sysdeps/powerpc/powerpc32/rtld-memset.c (aka string/memset.c) is used: https://sourceware.org/git/?p=glibc.git;a=blob;f=string/memset.c;h=9c213e82dc90f3eb426bc0b6c97ec5312b9d5c46;hb=HEAD What does not work: in '-O2 -mcpu=7450' mode ./sysdeps/powerpc/powerpc32/power4/multiarch/rtld-memset.S (aka sysdeps/powerpc/powerpc32/power4/memset.S) is used: https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/powerpc32/power4/memset.S;h=f4ada9afc991bdbddedc99815bc17209b64cae6e;hb=HEAD When it attempts to initialize .sbss / .iplt /.bss (all should be zeroed out) it fails to do so. __exit_funcs_lock is in .sbss. https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/powerpc32/rtld-memset.c;h=f3ed8ad1e74b6bbf9af8764b37c140179767744e;hb=HEAD says why memset.c is preferred because sysdeps/powerpc/powerpc32/power4/memset.S does not really work not many CPUs due to hardcoded cache-block=128: """ 1 /* PPCA2 has a different cache-line size than the usual 128 bytes. To avoid 2 using code that assumes cache-line size to be 128 bytes (with dcbz 3 instructions) we use the generic code instead. */ 4 #include <string/memset.c> """ For me qemu sets cache-block-size to 64 bytes and thus memsets only 64 of 128 bytes at each iteration leaving uninitialized holes in large chunks.
sysdeps/powerpc/powerpc32/power7/memset.S used by sysdeps/powerpc/powerpc32/power4/multiarch/memset-power7.S also assumes dcbz to cover 128 bytes at a time. This breaks memset() for normal (non-rtld) case.
AFAICS, powerpc 7450 can't run POWER4 code. So, this processor shouldn't be running POWER4 or POWER7 code. The question that needs to be answered is: why is your build getting them? I tried to reproduce your build, but I did not get any POWER4 files: configure --host=powerpc-linux-gnu --prefix=/usr CC="powerpc-linux-gnu-gcc" CFLAGS="-O2 -ggdb3 -mcpu=7450" $ grep submachine config.log libc_cv_cc_submachine='' submachine='' I used commit ID 756c306502498f999fdd494477b9cea1b45e4faf. What are you getting in your config.log?
Created attachment 12793 [details] ppc7450-config.log ppc7450-config.log is a config.log from ../glibc /configure --host=powerpc-unknown-linux-gnu --prefix=/usr \ CC="powerpc-unknown-linux-gnu-gcc -mcpu=7450" \ CFLAGS="-O2 -ggdb3 -mcpu=7450"
(In reply to Tulio Magno Quites Machado Filho from comment #2) > AFAICS, powerpc 7450 can't run POWER4 code. So, this processor shouldn't be > running POWER4 or POWER7 code. > The question that needs to be answered is: why is your build getting them? Oh, I had no idea. Mechanically power7 is detected at sysdeps/powerpc/preconfigure.ac: $ echo 'int foo () { return 0; }' | powerpc-unknown-linux-gnu-gcc-10.2.0 -S -frecord-gcc-switches -xc -o - - | fgrep machine .machine ppc $ echo 'int foo () { return 0; }' | powerpc-unknown-linux-gnu-gcc-10.2.0 -mcpu=7450 -S -frecord-gcc-switches -xc -o - - | fgrep machine .machine power7 Is it a gcc bug? > I tried to reproduce your build, but I did not get any POWER4 files: > configure --host=powerpc-linux-gnu --prefix=/usr CC="powerpc-linux-gnu-gcc" > CFLAGS="-O2 -ggdb3 -mcpu=7450" > > $ grep submachine config.log > libc_cv_cc_submachine='' > submachine='' For me -mcpu=7450 enabled mutilarch as well. Do you get it as well? > I used commit ID 756c306502498f999fdd494477b9cea1b45e4faf. > > What are you getting in your config.log? Attached https://sourceware.org/bugzilla/attachment.cgi?id=12793, should be done against the same commit.
(In reply to Sergei Trofimovich from comment #4) > (In reply to Tulio Magno Quites Machado Filho from comment #2) > > AFAICS, powerpc 7450 can't run POWER4 code. So, this processor shouldn't be > > running POWER4 or POWER7 code. > > The question that needs to be answered is: why is your build getting them? > > Oh, I had no idea. > > Mechanically power7 is detected at sysdeps/powerpc/preconfigure.ac: > > $ echo 'int foo () { return 0; }' | powerpc-unknown-linux-gnu-gcc-10.2.0 -S > -frecord-gcc-switches -xc -o - - | fgrep machine > .machine ppc > $ echo 'int foo () { return 0; }' | powerpc-unknown-linux-gnu-gcc-10.2.0 > -mcpu=7450 -S -frecord-gcc-switches -xc -o - - | fgrep machine > .machine power7 > > Is it a gcc bug? CCing gcc power maintainers. My naive grep suggests -mcpu=7450 should be ppc+altivec only and not power7: gcc/config/rs6000/driver-rs6000.c: """ { "7450", "-mppc %{!mvsx:%{!maltivec:-maltivec}}" }, "" gcc/config/rs6000/rs6000.c derives '.machine' as: """ #ifdef USING_ELFOS_H const char *rs6000_machine; const char * rs6000_machine_from_flags (void) { HOST_WIDE_INT flags = rs6000_isa_flags; /* Disable the flags that should never influence the .machine selection. */ flags &= ~(OPTION_MASK_PPC_GFXOPT | OPTION_MASK_PPC_GPOPT); if ((flags & (ISA_3_1_MASKS_SERVER & ~ISA_3_0_MASKS_SERVER)) != 0) return "power10"; if ((flags & (ISA_3_0_MASKS_SERVER & ~ISA_2_7_MASKS_SERVER)) != 0) return "power9"; if ((flags & (ISA_2_7_MASKS_SERVER & ~ISA_2_6_MASKS_SERVER)) != 0) return "power8"; if ((flags & (ISA_2_6_MASKS_SERVER & ~ISA_2_5_MASKS_SERVER)) != 0) return "power7"; if ((flags & (ISA_2_5_MASKS_SERVER & ~ISA_2_4_MASKS)) != 0) return "power6"; if ((flags & (ISA_2_4_MASKS & ~ISA_2_1_MASKS)) != 0) return "power5"; if ((flags & ISA_2_1_MASKS) != 0) return "power4"; if ((flags & OPTION_MASK_POWERPC64) != 0) return "ppc64"; return "ppc"; } void emit_asm_machine (void) { fprintf (asm_out_file, "\t.machine %s\n", rs6000_machine); } #endif """
"power7" is selected because (ISA_2_6_MASKS_SERVER & ~ISA_2_5_MASKS_SERVER) contains OPTION_MASK_ALTIVEC, and mcpu=7450 adds OPTION_MASK_ALTIVEC to rs6000_isa_flags. The whole logic in rs6000_machine_from_flags is busted. It should check that _all_ flags are present. Please file a bug with gcc.
(In reply to Andreas Schwab from comment #6) > "power7" is selected because (ISA_2_6_MASKS_SERVER & ~ISA_2_5_MASKS_SERVER) > contains OPTION_MASK_ALTIVEC, and mcpu=7450 adds OPTION_MASK_ALTIVEC to > rs6000_isa_flags. The whole logic in rs6000_machine_from_flags is busted. > It should check that _all_ flags are present. Please file a bug with gcc. Sounds good. What should '.machine' contain for -mcpu=7450? 'ppc'? I'm asking because I'm not sure what '.machine' means for gas: upper bound on available ISA or lower bound?
.machine sets the upper bound accepted by the assembler. It should match the mapping in the asm_names table in driver-rs6000.c.
Nice catch! This is only happening with GCC 10: $ gcc-10 -S -m32 -mcpu=7450 -frecord-gcc-switches -xc -o - - < /dev/null | grep -E 'mcpu|machine' .machine power7 .ascii "-mcpu=7450" $ gcc-9 -S -m32 -mcpu=7450 -frecord-gcc-switches -xc -o - - < /dev/null | grep -E 'mcpu|machine' .ascii "-mcpu=7450"
This is gcc.gnu.org/PR96786 now. Thanks!