Bug 161128 - gcc 4.2.1 ARM produces bad code with -fstack-protector
Summary: gcc 4.2.1 ARM produces bad code with -fstack-protector
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: Unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-arm (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-09-29 16:50 UTC by Naoyuki Tai
Modified: 2011-11-18 15:10 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Naoyuki Tai 2011-09-29 16:50:12 UTC
This is first manifested as arm/154189, but any application or library that uses -fstack-protector causes crash due to the compiler bug.
So far, I discovered this in lang/perl5.xx and net/avahi-app.

Here is one of manifestation from perl5.10.
This is the assembler output of locale.c in perl5.10, with no -fstack-protector.

Perl_new_collate:
@ args = 0, pretend = 0, frame = 104
@ frame_needed = 1, uses_anonymous_args = 0
mov ip, sp
stmfd sp!, {r4, r5, r6, fp, ip, lr, pc}
sub fp, ip, #4
sub sp, sp, #104
ldr r6, .L48
.LPIC2:
add r6, pc, r6
subs r5, r0, #0
bne .L31
ldr r3, .L48+4

And the data segment .L48 is
L48:
.word _GLOBAL_OFFSET_TABLE_-(.LPIC2+8)
.word PL_collation_name(GOT)


Here is the assembler output of locale.c with the -fstack-protector.
Perl_new_collate:
@ args = 0, pretend = 0, frame = 104
@ frame_needed = 1, uses_anonymous_args = 0
mov ip, sp
stmfd sp!, {r4, r5, r6, fp, ip, lr, pc}
sub fp, ip, #4
sub sp, sp, #104
ldr r6, .L49
.LPIC2:
add r6, pc, r6
ldr r3, .L49+4

And the data segment is

.L49:
.word _GLOBAL_OFFSET_TABLE_-(.LPIC2+8)
.word __stack_chk_guard(GOT)
.word PL_collation_name(GOT)

Notice the last "ldr r3, .L49+4".
It is loading r3 register from __stack_chk_guard(GOT) instead of
PL_collation_name(GOT).
So, I think that the arm backend has a bug that it is producing wrong
offsets in the data segment when the stack protector is used.
After noticing this, I took out the "-fstack-protector" from build and
the build succeeds.
It may be the problem that the combination of -fPIC and
-fstack-protector is used.
In any case, it is clear that the GCC's arm backend has a bug.

cc --version
cc (GCC) 4.2.1 20070719 [FreeBSD]
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Fix: 

Obviously, the correct fix is to fix the compiler, and I have no idea how.

If you need these ports to run without crash, after "make configure", take out the -fstack-protector from the Makefiles and what not under expanded "work" directory.
Alternatively, modify the C compiler to ignore -fstack-protector directive.
How-To-Repeat: Method 1:
Build lang/perl.5.12 on arm.

Method 2:
Build net/avahi-app on arm and run. avahi-daemon crashes.
Comment 1 Fabien THOMAS 2011-11-08 09:44:30 UTC
This is a known gcc bug and i've found that this fix correct the problem:

http://people.freebsd.org/~fabient/patch-arm_gcc_stackprotector_pic

The related gcc bug:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35965

Fabien
Comment 2 dfilter service freebsd_committer freebsd_triage 2011-11-09 16:14:41 UTC
Author: fabient
Date: Wed Nov  9 15:59:02 2011
New Revision: 227391
URL: http://svn.freebsd.org/changeset/base/227391

Log:
  Import gcc fix for -fstack-protector that produces segfaulting
  binaries on arm/armel.
  
  Related gcc bug:
  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35965
  
  PR: 161128
  MFC after: 1 week

Modified:
  head/contrib/gcc/config/arm/arm.c

Modified: head/contrib/gcc/config/arm/arm.c
==============================================================================
--- head/contrib/gcc/config/arm/arm.c	Wed Nov  9 15:21:48 2011	(r227390)
+++ head/contrib/gcc/config/arm/arm.c	Wed Nov  9 15:59:02 2011	(r227391)
@@ -3217,7 +3217,8 @@ legitimize_pic_address (rtx orig, enum m
 	  gcc_assert (!no_new_pseudos);
 	  if (arm_pic_register != INVALID_REGNUM)
 	    {
-	      cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
+	      if (!cfun->machine->pic_reg)
+		cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
 
 	      /* Play games to avoid marking the function as needing pic
 		 if we are being called as part of the cost-estimation
@@ -3229,7 +3230,8 @@ legitimize_pic_address (rtx orig, enum m
 	    {
 	      rtx seq;
 
-	      cfun->machine->pic_reg = gen_reg_rtx (Pmode);
+	      if (!cfun->machine->pic_reg)
+		  cfun->machine->pic_reg = gen_reg_rtx (Pmode);
 
 	      /* Play games to avoid marking the function as needing pic
 		 if we are being called as part of the cost-estimation
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 3 Fabien Thomas freebsd_committer freebsd_triage 2011-11-09 16:39:57 UTC
State Changed
From-To: open->patched

Committed. Waiting MFC / feedback.
Comment 4 dfilter service freebsd_committer freebsd_triage 2011-11-16 14:33:41 UTC
Author: fabient
Date: Wed Nov 16 14:33:30 2011
New Revision: 227551
URL: http://svn.freebsd.org/changeset/base/227551

Log:
  MFC r227391:
  Import gcc fix for -fstack-protector that produces segfaulting
  binaries on arm/armel.
  
  Related gcc bug:
  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35965
  
  Author kindly accepted that all of his patches can be use as GPLv2.
  
  PR:	161128

Modified:
  stable/8/contrib/gcc/config/arm/arm.c
Directory Properties:
  stable/8/contrib/gcc/   (props changed)

Modified: stable/8/contrib/gcc/config/arm/arm.c
==============================================================================
--- stable/8/contrib/gcc/config/arm/arm.c	Wed Nov 16 10:11:55 2011	(r227550)
+++ stable/8/contrib/gcc/config/arm/arm.c	Wed Nov 16 14:33:30 2011	(r227551)
@@ -3217,7 +3217,8 @@ legitimize_pic_address (rtx orig, enum m
 	  gcc_assert (!no_new_pseudos);
 	  if (arm_pic_register != INVALID_REGNUM)
 	    {
-	      cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
+	      if (!cfun->machine->pic_reg)
+		cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
 
 	      /* Play games to avoid marking the function as needing pic
 		 if we are being called as part of the cost-estimation
@@ -3229,7 +3230,8 @@ legitimize_pic_address (rtx orig, enum m
 	    {
 	      rtx seq;
 
-	      cfun->machine->pic_reg = gen_reg_rtx (Pmode);
+	      if (!cfun->machine->pic_reg)
+		  cfun->machine->pic_reg = gen_reg_rtx (Pmode);
 
 	      /* Play games to avoid marking the function as needing pic
 		 if we are being called as part of the cost-estimation
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 5 dfilter service freebsd_committer freebsd_triage 2011-11-16 14:38:02 UTC
Author: fabient
Date: Wed Nov 16 14:37:47 2011
New Revision: 227552
URL: http://svn.freebsd.org/changeset/base/227552

Log:
  MFC r227391:
  Import gcc fix for -fstack-protector that produces segfaulting
  binaries on arm/armel.
  
  Related gcc bug:
  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35965
  
  Author kindly accepted that all of his patches can be use as GPLv2.
  
  PR:	161128

Modified:
  stable/7/contrib/gcc/config/arm/arm.c
Directory Properties:
  stable/7/contrib/gcc/   (props changed)

Modified: stable/7/contrib/gcc/config/arm/arm.c
==============================================================================
--- stable/7/contrib/gcc/config/arm/arm.c	Wed Nov 16 14:33:30 2011	(r227551)
+++ stable/7/contrib/gcc/config/arm/arm.c	Wed Nov 16 14:37:47 2011	(r227552)
@@ -3217,7 +3217,8 @@ legitimize_pic_address (rtx orig, enum m
 	  gcc_assert (!no_new_pseudos);
 	  if (arm_pic_register != INVALID_REGNUM)
 	    {
-	      cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
+	      if (!cfun->machine->pic_reg)
+		cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
 
 	      /* Play games to avoid marking the function as needing pic
 		 if we are being called as part of the cost-estimation
@@ -3229,7 +3230,8 @@ legitimize_pic_address (rtx orig, enum m
 	    {
 	      rtx seq;
 
-	      cfun->machine->pic_reg = gen_reg_rtx (Pmode);
+	      if (!cfun->machine->pic_reg)
+		  cfun->machine->pic_reg = gen_reg_rtx (Pmode);
 
 	      /* Play games to avoid marking the function as needing pic
 		 if we are being called as part of the cost-estimation
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 6 dfilter service freebsd_committer freebsd_triage 2011-11-18 14:42:07 UTC
Author: fabient
Date: Fri Nov 18 14:41:48 2011
New Revision: 227664
URL: http://svn.freebsd.org/changeset/base/227664

Log:
  MFC r227391:
  Import gcc fix for -fstack-protector that produces segfaulting
  binaries on arm/armel.
  
  Related gcc bug:
  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35965
  
  Author kindly accepted that all of his patches can be use as GPLv2.
  
  PR: 161128
  Approved by: re (kib)

Modified:
  stable/9/contrib/gcc/config/arm/arm.c
Directory Properties:
  stable/9/contrib/gcc/   (props changed)

Modified: stable/9/contrib/gcc/config/arm/arm.c
==============================================================================
--- stable/9/contrib/gcc/config/arm/arm.c	Fri Nov 18 11:18:59 2011	(r227663)
+++ stable/9/contrib/gcc/config/arm/arm.c	Fri Nov 18 14:41:48 2011	(r227664)
@@ -3217,7 +3217,8 @@ legitimize_pic_address (rtx orig, enum m
 	  gcc_assert (!no_new_pseudos);
 	  if (arm_pic_register != INVALID_REGNUM)
 	    {
-	      cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
+	      if (!cfun->machine->pic_reg)
+		cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
 
 	      /* Play games to avoid marking the function as needing pic
 		 if we are being called as part of the cost-estimation
@@ -3229,7 +3230,8 @@ legitimize_pic_address (rtx orig, enum m
 	    {
 	      rtx seq;
 
-	      cfun->machine->pic_reg = gen_reg_rtx (Pmode);
+	      if (!cfun->machine->pic_reg)
+		  cfun->machine->pic_reg = gen_reg_rtx (Pmode);
 
 	      /* Play games to avoid marking the function as needing pic
 		 if we are being called as part of the cost-estimation
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 7 dfilter service freebsd_committer freebsd_triage 2011-11-18 14:56:19 UTC
Author: fabient
Date: Fri Nov 18 14:56:06 2011
New Revision: 227665
URL: http://svn.freebsd.org/changeset/base/227665

Log:
  MFC r227391:
  Import gcc fix for -fstack-protector that produces segfaulting
  binaries on arm/armel.
  
  Related gcc bug:
  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35965
  
  Author kindly accepted that all of his patches can be use as GPLv2.
  
  PR: 161128
  Approved by: re (kib)

Modified:
  releng/9.0/contrib/gcc/config/arm/arm.c
Directory Properties:
  releng/9.0/contrib/gcc/   (props changed)

Modified: releng/9.0/contrib/gcc/config/arm/arm.c
==============================================================================
--- releng/9.0/contrib/gcc/config/arm/arm.c	Fri Nov 18 14:41:48 2011	(r227664)
+++ releng/9.0/contrib/gcc/config/arm/arm.c	Fri Nov 18 14:56:06 2011	(r227665)
@@ -3217,7 +3217,8 @@ legitimize_pic_address (rtx orig, enum m
 	  gcc_assert (!no_new_pseudos);
 	  if (arm_pic_register != INVALID_REGNUM)
 	    {
-	      cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
+	      if (!cfun->machine->pic_reg)
+		cfun->machine->pic_reg = gen_rtx_REG (Pmode, arm_pic_register);
 
 	      /* Play games to avoid marking the function as needing pic
 		 if we are being called as part of the cost-estimation
@@ -3229,7 +3230,8 @@ legitimize_pic_address (rtx orig, enum m
 	    {
 	      rtx seq;
 
-	      cfun->machine->pic_reg = gen_reg_rtx (Pmode);
+	      if (!cfun->machine->pic_reg)
+		  cfun->machine->pic_reg = gen_reg_rtx (Pmode);
 
 	      /* Play games to avoid marking the function as needing pic
 		 if we are being called as part of the cost-estimation
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 8 Fabien Thomas freebsd_committer freebsd_triage 2011-11-18 14:58:14 UTC
State Changed
From-To: patched->closed

All patches done (stable/7, stable/8, stable/9, releng/9.0)