On Sun, Jun 04, 2017 at 04:40:17AM -0400, Bryan Steele wrote: > "As Shmuel reported in > <https://gcc.gnu.org/ml/gcc-help/2017-03/msg00009.html>, > on x86-64 small structures in automatic storage are aligned to 16 bytes. > This seems to be because of a mix-up between bits and bytes in the i386 > target code. > > * config/i386/i386.c (ix86_local_alignment): Align most aggregates > of 16 bytes and more to 16 bytes, not those of 16 bits and more." > > https://gcc.gnu.org/git/?p=gcc.git;a=commitdiff;h=b44e9be23d38be8997ae64d7509ac22cb4c556d6 > > It might be worth fixing this in ports gcc 4.9, found by tedu@ in 2014 > and committed by martynas@ to base gcc4 shortly later. > > http://www.tedunangst.com/flak/post/my-stack-protector-wasnt-working > http://marc.info/?l=openbsd-cvs&m=139895377300712&w=2 > http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/gnu/gcc/gcc/config/i386/i386.c.diff?r1=1.3&r2=1.4&f=h > > -Bryan. > > Index: Makefile > =================================================================== > RCS file: /cvs/ports/lang/gcc/4.9/Makefile,v > retrieving revision 1.47 > diff -u -p -u -r1.47 Makefile > --- Makefile 4 Mar 2017 21:59:55 -0000 1.47 > +++ Makefile 4 Jun 2017 08:36:12 -0000 > @@ -4,7 +4,7 @@ ONLY_FOR_ARCHS = amd64 arm hppa i386 mip > DPB_PROPERTIES = parallel > > V = 4.9.4 > -REVISION = 4 > +REVISION = 5 > FULL_VERSION = $V > FULL_PKGVERSION = $V > > Index: patches/patch-gcc_config_i386_i386_c > =================================================================== > RCS file: /cvs/ports/lang/gcc/4.9/patches/patch-gcc_config_i386_i386_c,v > retrieving revision 1.4 > diff -u -p -u -r1.4 patch-gcc_config_i386_i386_c > --- patches/patch-gcc_config_i386_i386_c 1 Sep 2016 17:30:33 -0000 > 1.4 > +++ patches/patch-gcc_config_i386_i386_c 4 Jun 2017 08:36:12 -0000 > @@ -1,6 +1,6 @@ > $OpenBSD: patch-gcc_config_i386_i386_c,v 1.4 2016/09/01 17:30:33 pascal Exp $ > ---- gcc/config/i386/i386.c.orig Mon Aug 1 18:03:41 2016 > -+++ gcc/config/i386/i386.c Sat Aug 6 19:19:04 2016 > +--- gcc/config/i386/i386.c.orig Mon Aug 1 12:03:41 2016 > ++++ gcc/config/i386/i386.c Sun Jun 4 04:30:01 2017 > @@ -2307,6 +2307,8 @@ struct ix86_frame > HOST_WIDE_INT reg_save_offset; > HOST_WIDE_INT sse_reg_save_offset; > @@ -18,13 +18,22 @@ $OpenBSD: patch-gcc_config_i386_i386_c,v > frame->nregs = ix86_nsaved_regs (); > frame->nsseregs = ix86_nsaved_sseregs (); > > -@@ -10903,6 +10906,9 @@ ix86_expand_prologue (void) > - m->fs.sp_offset = INCOMING_FRAME_SP_OFFSET; > +@@ -10904,6 +10907,9 @@ ix86_expand_prologue (void) > m->fs.realigned = true; > } > -+ > + > + if (warn_stack_larger_than && frame.local_size > stack_larger_than_size) > + warning (OPT_Wstack_larger_than_, "stack usage is %ld bytes", > frame.local_size); > - > ++ > int_registers_saved = (frame.nregs == 0); > sse_registers_saved = (frame.nsseregs == 0); > + > +@@ -26860,7 +26866,7 @@ ix86_local_alignment (tree exp, enum machine_mode > mode > + != TYPE_MAIN_VARIANT (va_list_type_node))) > + && TYPE_SIZE (type) > + && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST > +- && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 16 > ++ && (TREE_INT_CST_LOW (TYPE_SIZE (type)) >= 128 > + || TREE_INT_CST_HIGH (TYPE_SIZE (type))) && align < 128) > + return 128; > + }
This will probably require library and ports bumps, but here is an example to better demonstrate the issue: #include <stdio.h> #include <string.h> int main() { char buf[15]; strcpy(buf, "1234567890abcdef"); printf("%s", buf); } # base gcc 4.2.1 $ gcc ssp-test.c -o ssp-test /tmp//cc6vEhU3.o: In function `main': ssp-test.c:(.text+0x21): warning: warning: strcpy() is almost always misused, please use strlcpy() $ ./ssp-test Abort trap # base clang 4.0.0 $ /usr/bin/clang ssp-test.c -o ssp-test-clang1 /tmp/ssp-test-3faff4.o: In function `main': ssp-test.c:(.text+0x31): warning: warning: strcpy() is almost always misused, pl ease use strlcpy() $ ./ssp-test-clang1 Abort trap # ports clang 4.0.0 $ /usr/local/bin/clang ssp-test.c -o ssp-test-clang2 /tmp/ssp-test-f372af.o: In function `main': ssp-test.c:(.text+0x31): warning: warning: strcpy() is almost always misused, pl ease use strlcpy() $ ./ssp-test-clang2 Abort trap # ports egcc 4.9.4 $ egcc ssp-test.c -o ssp-test-egcc # ??? $ ./ssp-test-egcc 1234567890abcdef $ $ egcc -fno-builtin-strcpy ssp-test.c -o ssp-test-egcc /tmp//ccU4UBvd.o: In function `main': ssp-test.c:(.text+0x24): warning: warning: strcpy() is almost always misused, please use strlcpy() $ ./ssp-test-egcc 1234567890abcdef $ $ readelf -a ssp-test-egcc | grep smash 000000200fc8 000f00000007 R_X86_64_JUMP_SLO 0000000000000000 __stack_smash_handler + 0 15: 0000000000000000 281 FUNC GLOBAL DEFAULT UND __stack_smash_handler 30: 0000000000000000 281 FUNC GLOBAL DEFAULT UND __stack_smash_handler$