NetBSD Problem Report #54827

From www@netbsd.org  Thu Jan  2 21:42:38 2020
Return-Path: <www@netbsd.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 034897A14B
	for <gnats-bugs@gnats.NetBSD.org>; Thu,  2 Jan 2020 21:42:38 +0000 (UTC)
Message-Id: <20200102214237.31E5C7A1AB@mollari.NetBSD.org>
Date: Thu,  2 Jan 2020 21:42:37 +0000 (UTC)
From: uwe@stderr.spb.ru
Reply-To: uwe@stderr.spb.ru
To: gnats-bugs@NetBSD.org
Subject: alloca() is broken in gcc 8 on powerpc
X-Send-Pr-Version: www-1.0

>Number:         54827
>Category:       port-macppc
>Synopsis:       alloca() is broken in gcc 8 on powerpc
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    port-macppc-maintainer
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 02 21:45:00 +0000 2020
>Closed-Date:    Wed Jan 22 22:24:43 +0000 2020
>Last-Modified:  Wed Jan 22 22:24:43 +0000 2020
>Originator:     Valery Ushakov
>Release:        NetBSD 9.99.32
>Organization:
>Environment:
NetBSD snips.stderr.spb.ru 9.99.32 NetBSD 9.99.32 (GENERIC) #2: Thu Jan  2 06:50:25 MSK 2020  uwe@majava:/home/uwe/work/netbsd/cvs/src/sys/arch/macppc/compile/GENERIC macppc

>Description:
powerpc ports were switched to gcc-8 on 2019-12-14.  In a system built
after that date cc1 gets a segmentation fault and gdb cannot start.

$ cc --version | sed 1q
cc (nb1 20190930) 8.3.0
$ > empty.c
$ /usr/libexec/cc1 empty.c
<built-in>: internal compiler error: Segmentation fault
...
$


$ gdb
Undefined save command: "tracepoints".  Try "help save".
$ 

Full details and initial analysis in a follow-up mail as the margins
of this html form are too narrow...

>How-To-Repeat:

>Fix:

>Release-Note:

>Audit-Trail:
From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Fri, 3 Jan 2020 02:23:47 +0300

 When gdb starts up it registers its commands.  Among others:

   c = add_com_alias ("save-tracepoints", "save tracepoints", class_trace, 0);

 It parses "save tracepoints", finds "save", and finds its command
 table.  Then it needs to lookup "tracepoints" in that command table,
 and that ahppens in external/gpl3/gdb/dist/gdb/cli/cli-decode.c in
 lookup_cmd_1().  To perform the lookup it creates a copy of the
 command:

   command = (char *) alloca (len + 1);
   memcpy (command, *text, len);
   command[len] = '\0';

 and here we have:

 (gdb) p command
 $68 = 0xffffe1a0 "tracepoints"

 but then in the next line:

   /* Look it up.  */
   found = 0;

 the copied value in command is corrupted:

 (gdb) p command
 $84 = 0xffffe1a0 "tracepoi"


 That alloca call is compiled to:

 => <lookup_cmd_1+152>:      lwz     r9,16(r31)      # len
    <lookup_cmd_1+156>:      addi    r9,r9,1
    <lookup_cmd_1+160>:      addi    r9,r9,15
    <lookup_cmd_1+164>:      rlwinm  r9,r9,28,4,31
    <lookup_cmd_1+168>:      rlwinm  r9,r9,4,0,27    # len16 = round up to 16
    <lookup_cmd_1+172>:      lwz     r10,0(r1)	    # r10 = back chain
    <lookup_cmd_1+176>:      neg     r9,r9
    <lookup_cmd_1+180>:      stwux   r10,r1,r9	    # sp -= len16, store back chain
    <lookup_cmd_1+184>:      addi    r9,r1,8	    # skip back chain, LR slot
    <lookup_cmd_1+188>:      addi    r9,r9,15
    <lookup_cmd_1+192>:      rlwinm  r9,r9,28,4,31
    <lookup_cmd_1+196>:      rlwinm  r9,r9,4,0,27    # round up to 16
    <lookup_cmd_1+200>:      stw     r9,20(r31)	    # command = ...

 and then later found = 0 is compiled to:

 => <lookup_cmd_1+252>:      li      r9,0
    <lookup_cmd_1+256>:      stw     r9,8(r31)	    # <- overwrites!


 We start with %sp = %r31 = 0xffffe1a0.

 Length of "tracepoints" is 11, so alloca code pushes %sp 16 bytes,
 from 0xffffe1a0 to 0xffffe190.  The 8 bytes just below %sp are the
 back chain and the callee's LR slot, so it skips them.  Then it rounds
 up the result to 16 bytes and command gets the value 0xffffe1a0.  But
 11 bytes starting from that address are overlapping local variables
 that start at 8(%r31) (where 8 is the same offset that covers back
 chain and LR slot).


 Consider this minimized example, alloca-ppc.c:

 void bar(char *, int *);

 void
 foo()
 {
     char *p;
     int i;

     p = __builtin_alloca(11);
     i = 0;
     bar(p, &i);
 }


 $ powerpc--netbsd-gcc-7.4.0 -O0 -S -o alloca-ppc-7.s alloca-ppc.c 
 $ powerpc--netbsd-gcc-8.3.0 -O0 -S -o alloca-ppc-8.s alloca-ppc.c 
 $ diff -u -I ident alloca-ppc-7.s alloca-ppc-8.s 
 --- alloca-ppc-7.s 2020-01-03 00:30:37.304541529 +0300
 +++ alloca-ppc-8.s 2020-01-03 00:30:51.910782364 +0300
 @@ -17,7 +17,7 @@
    mr 31,1
    .cfi_def_cfa_register 31
    lwz 9,0(1)
 -  stwu 9,-32(1)
 +  stwu 9,-16(1)
    addi 9,1,8
    addi 9,9,15
    srwi 9,9,4


 Here gcc7 correctly accounts for 8 bytes it's going to skip later and
 moves %sp by roundup16(11 + 8) = 32 bytes.  OTOH, gcc8 doesn't take
 those 8 bytes into account and moves %sp only by roundup16(11) = 16
 bytes, creating an overlap.

 STARTING_FRAME_OFFSET and STACK_DYNAMIC_OFFSET in rs60000.h only got
 cosmetic changes between 7 and 8 imports in our tree, it seems.

 -uwe

From: "David H. Gutteridge" <david@gutteridge.ca>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Mon, 06 Jan 2020 15:40:42 -0500

 I'm not sure there is an upstream GCC fix for this, as I've found the
 issue is isolated to the GCC built as part of the NetBSD tooling. That
 is, I tested by building the following natively on a G4 Mac:

 GCC 8.3 from the NetBSD tree
 GCC 8.3 from pkgsrc
 GCC 9-snapshot from pkgsrc-wip

 The two GCCs from pkgsrc generate the correct instruction (as
 previously detailed), where the one from the NetBSD src tree does not,
 e.g.:

 --- alloca-ppc8.s       2020-01-06 08:49:43.908981299 -0500
 +++ alloca-ppc8native.s 2020-01-06 11:21:06.732122549 -0500
 @@ -7,17 +7,17 @@
  foo:
  .LFB0:
         .cfi_startproc
 -       stwu 1,-32(1)
 -       .cfi_def_cfa_offset 32
 +       stwu 1,-48(1)
 +       .cfi_def_cfa_offset 48
         mflr 0
 -       stw 0,36(1)
 -       stw 31,28(1)
 +       stw 0,52(1)
 +       stw 31,44(1)
         .cfi_offset 65, 4
         .cfi_offset 31, -4
         mr 31,1
         .cfi_def_cfa_register 31
         lwz 9,0(1)
 -       stwu 9,-32(1)
 +       stwu 9,-16(1)
         addi 9,1,8
         addi 9,9,15
         srwi 9,9,4
 @@ -30,7 +30,7 @@
         lwz 3,8(31)
         bl bar
         nop
 -       addi 11,31,32
 +       addi 11,31,48
         lwz 0,4(11)
         mtlr 0
         lwz 31,-4(11)
 @@ -42,4 +42,4 @@
         .cfi_endproc
  .LFE0:
         .size   foo, .-foo
 -       .ident  "GCC: (GNU) 8.3.0"
 +       .ident  "GCC: (NetBSD nb1 20190930) 8.3.0"

 I also looked through GCC PRs and commit entries, but didn't find
 anything that seemed to directly relate to this. (Having said that, I'm
 out of my depths here, so I could well have missed something!)

 Dave


From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@netbsd.org, port-macppc-maintainer@netbsd.org, 
	gnats-admin@netbsd.org, netbsd-bugs@netbsd.org, uwe@stderr.spb.ru
Cc: 
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Mon, 6 Jan 2020 16:35:34 -0500

 On Jan 6,  8:45pm, david@gutteridge.ca ("David H. Gutteridge") wrote:
 -- Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc

 | The following reply was made to PR port-macppc/54827; it has been noted by GNATS.
 | 
 | From: "David H. Gutteridge" <david@gutteridge.ca>
 | To: gnats-bugs@netbsd.org
 | Cc: 
 | Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
 | Date: Mon, 06 Jan 2020 15:40:42 -0500
 | 
 |  I'm not sure there is an upstream GCC fix for this, as I've found the
 |  issue is isolated to the GCC built as part of the NetBSD tooling. That
 |  is, I tested by building the following natively on a G4 Mac:
 |  
 |  GCC 8.3 from the NetBSD tree
 |  GCC 8.3 from pkgsrc
 |  GCC 9-snapshot from pkgsrc-wip
 |  
 |  The two GCCs from pkgsrc generate the correct instruction (as
 |  previously detailed), where the one from the NetBSD src tree does not,
 |  e.g.:
 |  
 |  --- alloca-ppc8.s       2020-01-06 08:49:43.908981299 -0500
 |  +++ alloca-ppc8native.s 2020-01-06 11:21:06.732122549 -0500
 |  @@ -7,17 +7,17 @@
 |   foo:
 |   .LFB0:
 |          .cfi_startproc
 |  -       stwu 1,-32(1)
 |  -       .cfi_def_cfa_offset 32
 |  +       stwu 1,-48(1)
 |  +       .cfi_def_cfa_offset 48
 |          mflr 0
 |  -       stw 0,36(1)
 |  -       stw 31,28(1)
 |  +       stw 0,52(1)
 |  +       stw 31,44(1)
 |          .cfi_offset 65, 4
 |          .cfi_offset 31, -4
 |          mr 31,1
 |          .cfi_def_cfa_register 31
 |          lwz 9,0(1)
 |  -       stwu 9,-32(1)
 |  +       stwu 9,-16(1)
 |          addi 9,1,8
 |          addi 9,9,15
 |          srwi 9,9,4
 |  @@ -30,7 +30,7 @@
 |          lwz 3,8(31)
 |          bl bar
 |          nop
 |  -       addi 11,31,32
 |  +       addi 11,31,48
 |          lwz 0,4(11)
 |          mtlr 0
 |          lwz 31,-4(11)
 |  @@ -42,4 +42,4 @@
 |          .cfi_endproc
 |   .LFE0:
 |          .size   foo, .-foo
 |  -       .ident  "GCC: (GNU) 8.3.0"
 |  +       .ident  "GCC: (NetBSD nb1 20190930) 8.3.0"
 |  
 |  I also looked through GCC PRs and commit entries, but didn't find
 |  anything that seemed to directly relate to this. (Having said that, I'm
 |  out of my depths here, so I could well have missed something!)

 I think that perhaps the order of the include files is affecting some
 of the stack related macros?

 christos

From: matthew green <mrg@eterna.com.au>
To: gnats-bugs@netbsd.org
Cc: port-macppc-maintainer@netbsd.org, gnats-admin@netbsd.org,
    netbsd-bugs@netbsd.org, uwe@stderr.spb.ru
Subject: re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Tue, 07 Jan 2020 15:15:18 +1100

 looking at the diff in external/gpl3/gcc/dist/gcc/config/rs6000,
 i see that we have a lot changes vs eg, vs gcc-8-3-0 import or
 the pkgsrc gcc 8 (which has zero rs6000/powerpc changes).

 they're for ppc64, but also several other ones.

 we also have patched config.gcc heavily for rs6000 and maybe
 more.

 things i would start with:
 - revert rs6000.c changes
 - revert config.gcc powerpc changes, and perhaps also the bit
   about default_gnu_indirect_function.
 - try to figure out how to revert type-definitions changes

 but nothing looks obvious to me.


 .mrg.

From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: "David H. Gutteridge" <david@gutteridge.ca>
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Wed, 8 Jan 2020 04:32:42 +0300

 On Mon, Jan 06, 2020 at 20:45:01 +0000, David H. Gutteridge wrote:

 >  The two GCCs from pkgsrc generate the correct instruction (as
 >  previously detailed), where the one from the NetBSD src tree does
 >  not

 Thanks a lot for doing that experiment.  Please, could you diff the .i
 files from the in-tree compiler and stock one from the pkgsrc?  The
 interesting files are rs6000.i, and maybe function.i and explow.i.  rm
 the .o file, run make, copy the command and re-run with -save-temps
 added.  Hopefully, that should point out which macros we've got wrong.

 -uwe

From: "David H. Gutteridge" <david@gutteridge.ca>
To: Valery Ushakov <uwe@stderr.spb.ru>, gnats-bugs@netbsd.org
Cc: 
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Tue, 14 Jan 2020 17:27:38 -0500

 On Wed, 2020-01-08 at 04:32 +0300, Valery Ushakov wrote:
 > On Mon, Jan 06, 2020 at 20:45:01 +0000, David H. Gutteridge wrote:
 > 
 > >  The two GCCs from pkgsrc generate the correct instruction (as
 > >  previously detailed), where the one from the NetBSD src tree does
 > >  not
 > 
 > Thanks a lot for doing that experiment.  Please, could you diff the .i
 > files from the in-tree compiler and stock one from the pkgsrc?  The
 > interesting files are rs6000.i, and maybe function.i and explow.i.  rm
 > the .o file, run make, copy the command and re-run with -save-temps
 > added.  Hopefully, that should point out which macros we've got wrong.

 I've generated the .ii (and also retained the .s) for rs6000.c,
 function.c, and explow.c. The pkgsrc version actually generates three
 sets of these files; I went with the directory that seemed most
 comparable (the other two having "old" and "stage-1" in their names,
 which I presume related to bootstrapping and such).

 A raw diff is too big to usefully post here. To gets something more
 meaningful, we'd have to strip all the differences in path names out,
 which I haven't looked at (yet).

 I've uploaded archives of each set of files as
 www.netbsd.org/~gutteridge/gcc8_native.tgz
 www.netbsd.org/~gutteridge/gcc8_pkgsrc.tgz

 Dave


From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: "David H. Gutteridge" <david@gutteridge.ca>
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Wed, 15 Jan 2020 18:26:48 +0300

 On Tue, Jan 14, 2020 at 22:30:02 +0000, David H. Gutteridge wrote:

 >  A raw diff is too big to usefully post here. To gets something more
 >  meaningful, we'd have to strip all the differences in path names out,
 >  which I haven't looked at (yet).

 Weird. From a very quick look I don't see any meaningful differences.
 For reference, here's the script I used to cull the diffs (hop gnats
 won't mangle it much)

 #!env bash
 # sorry, rc'ish <(cmd) syntax is so nice to use here :)

 # reduce differences
 # - pathnames
 # - line numbers in error messages
 # - default stack alignment: always 128 on netbsd, depends on isa otherwise
 # - default isa
 # - cpp whitespace difference: (8 \* 4) vs (\n\s+8 \n\s+\* 4)

 fixup_pkgsrc() {
     cat gcc8_pkgsrc/$1 | \
 	sed -e '/^#/d' \
     	    -e 's|\.\./\.\./gcc-8\.3\.0/||g' \
 	    -e 's|, [0-9][0-9]*, __FUNCTION__)|, 99999, __FUNCTION__)|g' \
 	    -e 's|(8 \* 4)|(\
  8\
  * 4)|g' \
 	    -e 's|(0x7fffffff \* 2U + 1U)|0xffffffffU|g' \
 	    -e 's|(((! ((global_options\.x_rs6000_isa_flags & (1ULL << 0)) != 0)) && !((global_options\.x_rs6000_isa_flags & (1ULL << 1)) != 0) && !global_options\.x_rs6000_altivec_abi && !((global_options\.x_rs6000_isa_flags & (1ULL << 43)) != 0)) ? 64 : 128)|128|g'
 }

 # +
 fixup_native() {
     cat gcc8_native/$1 | \
 	sed -e '/^#/d' \
     	    -e 's|/home/disciple/netbsd-current/src/tools/gcc/\.\./\.\./external/gpl3/gcc/dist/||g' \
 	    -e 's|, [0-9][0-9]*, __FUNCTION__)|, 99999, __FUNCTION__)|g' \
 	    -e 's|((1ULL << 41))|0|g' \
 	    -e 's|^[ 	][ 	]*8[ 	][ 	]*$| 8|' \
 	    -e 's|^[ 	][ 	]*\* 4| * 4|' \
 	    -e 's|putc_unlocked|putc|g'
 }

 diff -p -u <(fixup_pkgsrc $1) <(fixup_native $1)


 You'll get about 9K lines of header diffs that can be ignored.
 functions.ii and explow.ii have no diffs besides that.

 rs6000.ii has

 - whitespace in __builtin_foo ( vs __builtin_foo(
 - some stray src line numbers
 - SCALAR_FLOAT_MODE_P 0 vs 1 
 - rs6000_elf_reloc_rw_mask ifdef

 but all that is either trivial or irrelevant.

 -uwe

From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@netbsd.org, port-macppc-maintainer@netbsd.org, 
	gnats-admin@netbsd.org, netbsd-bugs@netbsd.org, uwe@stderr.spb.ru
Cc: 
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Wed, 15 Jan 2020 13:48:19 -0500

 On Jan 15,  3:30pm, uwe@stderr.spb.ru (Valery Ushakov) wrote:
 -- Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc

 | The following reply was made to PR port-macppc/54827; it has been noted by GNATS.
 | 
 | From: Valery Ushakov <uwe@stderr.spb.ru>
 | To: gnats-bugs@netbsd.org
 | Cc: "David H. Gutteridge" <david@gutteridge.ca>
 | Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
 | Date: Wed, 15 Jan 2020 18:26:48 +0300
 | 
 |  On Tue, Jan 14, 2020 at 22:30:02 +0000, David H. Gutteridge wrote:
 |  
 |  >  A raw diff is too big to usefully post here. To gets something more
 |  >  meaningful, we'd have to strip all the differences in path names out,
 |  >  which I haven't looked at (yet).
 |  
 |  Weird. From a very quick look I don't see any meaningful differences.
 |  For reference, here's the script I used to cull the diffs (hop gnats
 |  won't mangle it much)


 Is all the netbsd-specific config glue the same? Because I found differences
 caused by the order of include files changing...

 christos

From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Sat, 18 Jan 2020 20:24:58 +0300

 TL;DR: I suspect we might be inconsistently defining STACK_BOUNDARY.
 Its override in netbsd.h has this comment:

   /* Override STACK_BOUNDARY to use Altivec compliant one.  */

 I suspect some other define needs to be adjusted as well, but isn't.
 The bug doesn't happen with explicit -maltivec (that probably whacks
 that other value to be cosistent with "always altivec" STACK_BOUNDARY).



 I'm testing against stock gcc-8.3.0 cross-compiler configured with

   ./configure --target=powerpc--netbsd

 Running make to build it will eventually fail b/c the rest of the
 cross-toolchain is not present, but we don't care b/c by that time we
 already have "cc1" built, which is all that we really need here.


 $ cat main.c            # ----8<--------8<----
 #include <stdio.h>
 #include <string.h>

 void foo();

 int
 main()
 {
     foo();
     return 0;
 }


 void
 bar(char *s, int *pi)
 {
     printf("%p %p\n", s, pi);

     strcpy(s, "overwrite");
     printf("%#x\n", *pi);
 }



 $ cat alloca-test.c     # ----8<--------8<----
 void bar(char *, int *);

 void
 foo()
 {
     char *s;
     int i;

     s = __builtin_alloca(10);	/* sizeof("overwrite") */
     i = 0;
     bar(s, &i);
 }



 We are going to build all the interesting permutations, so here's the
 helper script.  -mregnames makes the output readable.  In-tree
 compiler emits CFI directives, but the stock compiler emits .eh_frame
 instead and seems to ignore -fdwarf2-cfi-asm, but eh_frame is even
 more convenient since we can ignore differences in it wholesale.


 $ cat runme.sh          # ----8<--------8<----
 CC1=.../gcc-8.3.0/host-x86_64-pc-linux-gnu/gcc/cc1	# stock gcc
 NB1=.../tools/libexec/gcc/powerpc--netbsd/8.3.0/cc1	# $TOOLDIR

 compile() {
     cc1=$1; kind=$2; in=$3
     base=out

     CC="$cc1 -quiet -fno-dwarf2-cfi-asm -mregnames $in"

     $CC -mno-altivec -O0 -o $base-$kind-no0.s
     $CC -mno-altivec -O2 -o $base-$kind-no2.s

     $CC -maltivec    -O0 -o $base-$kind-av0.s
     $CC -maltivec    -O2 -o $base-$kind-av2.s
 }

 compile $CC1 dist alloca-test.c
 compile $NB1 nb   alloca-test.c
 $ sh runme.sh
 $ ls *.s
 out-dist-av0.s	out-dist-no0.s	out-nb-av0.s  out-nb-no0.s
 out-dist-av2.s	out-dist-no2.s	out-nb-av2.s  out-nb-no2.s


 We can now confirm the problem using the .s file produced by the
 in-tree gcc8 compiler from -current with -O2 and without -maltivec.
 This test is done on my macppc 8-stable box.

 ppc$ cc -g -O0 main.c out-nb-no2.s && ./a.out 
 0xffffe1f0 0xffffe1f8
 0x65000000

 Allocated memory (0xffffe1f0 + 10 bytes) overlaps the stack slot where
 "i" lives (0xffffe1f8) so strcpy overwrites its value as we can see in
 the next output line ('e' is 0x65, macppc is big-endian).

 In-tree compiler with -maltivec produces the same (correct) output as
 the stock compiler with -maltivec:

 $ diff -u out-nb-av0.s out-dist-av0.s | sed '/eh_frame/q'
 --- out-nb-av0.s        2020-01-18 20:00:51.164188737 +0300
 +++ out-dist-av0.s      2020-01-18 20:00:51.096188833 +0300
 @@ -38,19 +38,19 @@
         blr
  .LFE0:
         .size   foo, .-foo
 -       .section        .eh_frame,"a",@progbits
 $ diff -u out-nb-av2.s out-dist-av2.s | sed '/eh_frame/q'
 --- out-nb-av2.s        2020-01-18 20:00:51.188188703 +0300
 +++ out-dist-av2.s      2020-01-18 20:00:51.104188822 +0300
 @@ -33,19 +33,19 @@
         blr
  .LFE0:
         .size   foo, .-foo
 -       .section        .eh_frame,"a",@progbits
 $ cc -g -O0 main.c out-nb-av2.s && ./a.out 
 0xffffe1f0 0xffffe200
 0



 The diff between in-tree without -maltivec (bad) and in-tree/stock
 with -maltivec (good) is:

 $ diff -u out-nb-no2.s out-dist-av2.s | sed '/eh_frame/q'
 --- out-nb-no2.s       2020-01-18 20:00:51.144188765 +0300
 +++ out-dist-av2.s     2020-01-18 20:00:51.104188822 +0300
 @@ -17,9 +17,9 @@
  .LCFI2:
 	stw %r0,52(%r1)
  .LCFI3:
 -	addi %r4,%r31,8
 +	addi %r4,%r31,16
  	stwu %r9,-16(%r1)
 -	stw %r10,8(%r31)
 +	stw %r10,16(%r31)
  	addi %r3,%r1,16
  	bl bar
  	addi %r11,%r31,48
 @@ [...]


 Someone with more ppc and gcc clue should look into what happens
 there.  My uneducated guess is that while our STACK_BOUNDARY is always
 16 bytes (NB: its value, 128, is in *bits*), some other alignment
 parameter is inconsistently 8 bytes without -maltivec and is 16 only
 with -maltivec.

 -uwe

From: matthew green <mrg@eterna.com.au>
To: gnats-bugs@netbsd.org
Cc: port-macppc-maintainer@netbsd.org, gnats-admin@netbsd.org,
    netbsd-bugs@netbsd.org, uwe@stderr.spb.ru
Subject: re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Sun, 19 Jan 2020 19:47:05 +1100

 a quick look at what -maltivec does that our STACK_BOUNDARY
 does, and it seems that maybe there are some hard coded 16
 vs 8 cases.. eg, rs6000.c:25131 in -current:

   save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;

 looks like the the one that matters.  there are a few of
 these type of conditionals in the code, though the others
 seem to all generate warnings, and this one is in the
 rs6000_stack_info() function.

 as a hack test, can you see if making that always 16 fixes
 the problem?  if so, i can figure out a less stupid way.
 if not, i'll configure my own test setup for it and see
 what else i can figure out.


 i remember why we do this.  the idea is that any code that
 is built with this compiler will work with altivec code
 intermingled with non altivec option code.

 thanks.


 .mrg.

From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: matthew green <mrg@eterna.com.au>
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Sun, 19 Jan 2020 18:32:32 +0300

 That doesn't seem to help.

 #if 0
   save_align = (TARGET_ALTIVEC_ABI || DEFAULT_ABI == ABI_DARWIN) ? 16 : 8;
 #else  /* XXX: uwe: fancy way to say 16 */
   save_align = STACK_BOUNDARY / BITS_PER_UNIT;
 #endif


 The output for -mno-altivec -O2 allocates larger stack frame:

 -       stwu %r1,-48(%r1)
 +       stwu %r1,-64(%r1)

 (plus corresponding changes down the code), but the rest is the same.

 Testing its output shows the bug is still there, it just happens 16
 bytes earlier:

 $ cc -g -O0 main.c out-nx-no2.s && ./a.out
 0xffffe1e0 0xffffe1e8
 0x65000000


 -uwe

From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: matthew green <mrg@eterna.com.au>
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Mon, 20 Jan 2020 06:27:20 +0300

 On Sun, Jan 19, 2020 at 08:50:01 +0000, matthew green wrote:

 >  a quick look at what -maltivec does that our STACK_BOUNDARY
 >  does, and it seems that maybe there are some hard coded 16
 >  vs 8 cases

 Actually, since we are stomping onto the first local variable I wonder
 if the one we want is RS6000_STARTING_FRAME_OFFSET that has the
 (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8 part.

 -uwe

From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: matthew green <mrg@eterna.com.au>
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Tue, 21 Jan 2020 17:18:19 +0300

 On Mon, Jan 20, 2020 at 03:30:02 +0000, Valery Ushakov wrote:

 > Actually, since we are stomping onto the first local variable I wonder
 > if the one we want is RS6000_STARTING_FRAME_OFFSET that has the
 > (TARGET_ALTIVEC || TARGET_VSX) ? 16 : 8 part.

 The following diff seems to help though I haven't yet tested variable
 length alloca.  The diff overrides two additional macros that have
 that 16 vs. 8 choice dependent on altivec to always use 16 to match
 our STACK_BOUNDARY.

 --- netbsd.h.~1.14.~	2019-10-02 12:53:42.597881037 +0300
 +++ netbsd.h	2020-01-21 16:45:53.231796140 +0300
 @@ -142,6 +142,20 @@
  #undef STACK_BOUNDARY
  #define STACK_BOUNDARY	128

 +/* XXX: uwe: override to match STACK_BOUNDARY */
 +#undef RS6000_STARTING_FRAME_OFFSET
 +#define RS6000_STARTING_FRAME_OFFSET					\
 +  (cfun->calls_alloca							\
 +   ? (RS6000_ALIGN (crtl->outgoing_args_size + RS6000_SAVE_AREA, 16))	\
 +   : (RS6000_ALIGN (crtl->outgoing_args_size, 16)			\
 +      + RS6000_SAVE_AREA))
 +
 +/* XXX: uwe: override to match STACK_BOUNDARY */
 +#undef STACK_DYNAMIC_OFFSET
 +#define STACK_DYNAMIC_OFFSET(FUNDECL)					\
 +  RS6000_ALIGN (crtl->outgoing_args_size.to_constant ()			\
 +		+ STACK_POINTER_OFFSET, 16)
 +
  /* Use standard DWARF numbering for DWARF debugging information.  */
  #define RS6000_USE_DWARF_NUMBERING



 -uwe

From: "Valeriy E. Ushakov" <uwe@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/54827 CVS commit: src/share/mk
Date: Wed, 22 Jan 2020 08:32:33 +0000

 Module Name:	src
 Committed By:	uwe
 Date:		Wed Jan 22 08:32:33 UTC 2020

 Modified Files:
 	src/share/mk: bsd.own.mk

 Log Message:
 Switch powerpc back to GCC 7 until we fix alloca() PR port-macppc/54827
 ok mrg@


 To generate a diff of this commit:
 cvs rdiff -u -r1.1173 -r1.1174 src/share/mk/bsd.own.mk

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Wed, 22 Jan 2020 17:23:19 +0300

 I think I found a real fix, though I have no idea why does it work and
 how the old code did ever work before :)

 As mentioned earlier, our in-tree rs6000/netbsd.h overrides
 STACK_BOUNDARY to always be 16 bytes:

   /* Override STACK_BOUNDARY to use Altivec compliant one.  */
   #undef STACK_BOUNDARY
   #define STACK_BOUNDARY	128


 Stock gcc rs6000/netbsd.h doesn't have that override, but still emits
 asm for stack frame aligned to 16 bytes.

 This is b/c the SYSV ABI that we use already mandates 16 bytes aligned
 stack frames (8 bytes alignment only seems to be used by the embedded
 EABI).  This is effected by rs6000/sysv4.h

   #undef PREFERRED_STACK_BOUNDARY
   #define PREFERRED_STACK_BOUNDARY 128

 It's included by tm.h before netbsd.h


 defaults.h takes care of defining PREFERRED_STACK_BOUNDARY if
 necessary

   /* If PREFERRED_STACK_BOUNDARY is not defined, set it to STACK_BOUNDARY.
      STACK_BOUNDARY is required.  */
   #ifndef PREFERRED_STACK_BOUNDARY
   #define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY
   #endif


 Another relevant comment can be found in combine-stack-adj.c:

    [...] It is of significantly more value to targets that define
    PREFERRED_STACK_BOUNDARY more aligned than STACK_BOUNDARY [...]


 So it looks like netbsd.h 1) overrides wrong define, 2) that is
 already overriden by a "base" header.  And so we ended up with
 STACK_BOUNDARY == PREFERRED_STACK_BOUNDARY == 16 instead of stock
 version STACK_BOUNDARY == 8 and PREFERRED_STACK_BOUNDARY == 16.

 I'm not qualified to comment on why ppc code is written the way it is
 (using STACK_BOUNDARY that is not actually used by the ABI it emits
 the code for) and what broke between 7 and 8 to make our old
 arrangement fail.  Dropping the override from netbsd.h makes in-tree
 compiler emit the same asm for all the four -O{0,2} -m{no-,}altivec
 combinations as the stock gcc for the alloca-test.c above.  The stack
 frames are still 16 bytes aligned (as mandated by SYSV ABI).


 --- netbsd.h.~1.14.~	    2020-01-22 16:31:12.806472210 +0300
 +++ netbsd.h		    2020-01-22 16:31:28.902491784 +0300
 @@ -138,10 +138,6 @@
  #define TRAMPOLINE_SIZE 48
  #endif

 -/* Override STACK_BOUNDARY to use Altivec compliant one.  */
 -#undef STACK_BOUNDARY
 -#define STACK_BOUNDARY	128
 -
  /* Use standard DWARF numbering for DWARF debugging information.  */
  #define RS6000_USE_DWARF_NUMBERING

 -uwe

From: Valery Ushakov <uwe@stderr.spb.ru>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: port-macppc/54827: alloca() is broken in gcc 8 on powerpc
Date: Thu, 23 Jan 2020 00:42:34 +0300

 [forgot to xref the pr from the commit message, bouncing]

 Module Name:	src
 Committed By:	uwe
 Date:		Wed Jan 22 21:39:43 UTC 2020

 Modified Files:
 	src/external/gpl3/gcc/dist/gcc/config/rs6000: netbsd.h

 Log Message:
 Do not override STACK_BOUNDARY in netbsd.h

 sysv4.h already overrides PREFERRED_STACK_BOUNDARY b/c SYSV ABI
 requires 16 bytes alignment for %sp anyway and so we already get that
 for free.

 More importantly this also fixes alloca() in GCC 8, that was somehow
 confused by that STACK_BOUNDARY value we had and created a buffer that
 overlapped top local variable slots.


 To generate a diff of this commit:
 cvs rdiff -u -r1.14 -r1.15 \
     src/external/gpl3/gcc/dist/gcc/config/rs6000/netbsd.h

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Valeriy E. Ushakov" <uwe@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/54827 CVS commit: src/share/mk
Date: Wed, 22 Jan 2020 21:46:07 +0000

 Module Name:	src
 Committed By:	uwe
 Date:		Wed Jan 22 21:46:07 UTC 2020

 Modified Files:
 	src/share/mk: bsd.own.mk

 Log Message:
 Switch powerpc to GCC 8 again now that alloca() is fixed.
 PR port-macppc/54827


 To generate a diff of this commit:
 cvs rdiff -u -r1.1174 -r1.1175 src/share/mk/bsd.own.mk

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->closed
State-Changed-By: uwe@NetBSD.org
State-Changed-When: Wed, 22 Jan 2020 22:24:43 +0000
State-Changed-Why:
Should be fixed now.


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.