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:
(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.