diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2014-12-18 11:09:28 -0800 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-01-06 15:38:25 -0800 |
commit | 4fc1b9d43cbce7571264a0011c87258b78252750 (patch) | |
tree | 93ec540f596de570077e84135d9e1a78ac4b67a4 /gold | |
parent | e7287c7f647870093b8ab5ffea0732ffdb8c4d66 (diff) | |
download | binutils-gdb-4fc1b9d43cbce7571264a0011c87258b78252750.tar.gz |
Handle stack split for x32
X32 uses cmp %fs:NN,%esp, lea NN(%rsp),%r10d, lea NN(%rsp),%r11d,
instead of cmp %fs:NN,%rsp, lea NN(%rsp),%r10, lea NN(%rsp),%r11.
This patch handles it.
PR gold/17729
* configure.ac (DEFAULT_TARGET_X86_64): Don't set for x32.
(DEFAULT_TARGET_X32): Set for x32.
* x86_64.cc (cmp_insn_32): New.
(lea_r10_insn_32): Likewise.
(lea_r11_insn_32): Likewise.
(cmp_insn_64): Likewise.
(lea_r10_insn_64): Likewise.
(lea_r11_insn_64): Likewise.
(Target_x86_64<size>::do_calls_non_split): Handle x32.
* testsuite/Makefile.am (check_SCRIPTS): Add split_x32.sh.
(check_DATA): Add split_x32 files.
(split_x32_[1234n].o): New targets.
(split_x32_[124]): New targets.
(split_x32_[1234r].stdout): New targets.
* testsuite/split_x32.sh: New file.
* testsuite/split_x32_1.s: Likewise.
* testsuite/split_x32_2.s: Likewise.
* testsuite/split_x32_3.s: Likewise.
* testsuite/split_x32_4.s: Likewise.
* testsuite/split_x32_n.s: Likewise.
* configure: Regenerated.
* testsuite/Makefile.in: Likewise.
Diffstat (limited to 'gold')
-rw-r--r-- | gold/ChangeLog | 27 | ||||
-rwxr-xr-x | gold/configure | 28 | ||||
-rw-r--r-- | gold/configure.ac | 15 | ||||
-rw-r--r-- | gold/testsuite/Makefile.am | 37 | ||||
-rw-r--r-- | gold/testsuite/Makefile.in | 55 | ||||
-rwxr-xr-x | gold/testsuite/split_x32.sh | 55 | ||||
-rw-r--r-- | gold/testsuite/split_x32_1.s | 33 | ||||
-rw-r--r-- | gold/testsuite/split_x32_2.s | 33 | ||||
-rw-r--r-- | gold/testsuite/split_x32_3.s | 22 | ||||
-rw-r--r-- | gold/testsuite/split_x32_4.s | 23 | ||||
-rw-r--r-- | gold/testsuite/split_x32_n.s | 12 | ||||
-rw-r--r-- | gold/x86_64.cc | 33 |
12 files changed, 357 insertions, 16 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog index af56066d5a6..93529fe5364 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,4 +1,31 @@ 2015-01-06 H.J. Lu <hongjiu.lu@intel.com> + Cary Coutant <ccoutant@google.com> + + PR gold/17729 + * configure.ac (DEFAULT_TARGET_X86_64): Don't set for x32. + (DEFAULT_TARGET_X32): Set for x32. + * x86_64.cc (cmp_insn_32): New. + (lea_r10_insn_32): Likewise. + (lea_r11_insn_32): Likewise. + (cmp_insn_64): Likewise. + (lea_r10_insn_64): Likewise. + (lea_r11_insn_64): Likewise. + (Target_x86_64<size>::do_calls_non_split): Handle x32. + * testsuite/Makefile.am (check_SCRIPTS): Add split_x32.sh. + (check_DATA): Add split_x32 files. + (split_x32_[1234n].o): New targets. + (split_x32_[124]): New targets. + (split_x32_[1234r].stdout): New targets. + * testsuite/split_x32.sh: New file. + * testsuite/split_x32_1.s: Likewise. + * testsuite/split_x32_2.s: Likewise. + * testsuite/split_x32_3.s: Likewise. + * testsuite/split_x32_4.s: Likewise. + * testsuite/split_x32_n.s: Likewise. + * configure: Regenerated. + * testsuite/Makefile.in: Likewise. + +2015-01-06 H.J. Lu <hongjiu.lu@intel.com> PR gold/17809 * x86_64.cc (Target_x86_64<size>::Relocate::tls_ie_to_le): Handle diff --git a/gold/configure b/gold/configure index 7d7b849331b..23e473542e8 100755 --- a/gold/configure +++ b/gold/configure @@ -688,6 +688,8 @@ DEFAULT_TARGET_MIPS_FALSE DEFAULT_TARGET_MIPS_TRUE DEFAULT_TARGET_TILEGX_FALSE DEFAULT_TARGET_TILEGX_TRUE +DEFAULT_TARGET_X32_FALSE +DEFAULT_TARGET_X32_TRUE DEFAULT_TARGET_X86_64_FALSE DEFAULT_TARGET_X86_64_TRUE DEFAULT_TARGET_SPARC_FALSE @@ -3475,7 +3477,19 @@ else DEFAULT_TARGET_SPARC_FALSE= fi - if test "$targ_obj" = "x86_64"; then + target_x86_64=no + target_x32=no + if test "$targ_obj" = "x86_64"; then + case "$target" in + x86_64*-linux-gnux32) + target_x32=yes + ;; + *) + target_x86_64=yes + ;; + esac + fi + if test "$target_x86_64" = "yes"; then DEFAULT_TARGET_X86_64_TRUE= DEFAULT_TARGET_X86_64_FALSE='#' else @@ -3483,6 +3497,14 @@ else DEFAULT_TARGET_X86_64_FALSE= fi + if test "$target_x32" = "yes"; then + DEFAULT_TARGET_X32_TRUE= + DEFAULT_TARGET_X32_FALSE='#' +else + DEFAULT_TARGET_X32_TRUE='#' + DEFAULT_TARGET_X32_FALSE= +fi + if test "$targ_obj" = "tilegx"; then DEFAULT_TARGET_TILEGX_TRUE= DEFAULT_TARGET_TILEGX_FALSE='#' @@ -7811,6 +7833,10 @@ if test -z "${DEFAULT_TARGET_X86_64_TRUE}" && test -z "${DEFAULT_TARGET_X86_64_F as_fn_error "conditional \"DEFAULT_TARGET_X86_64\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi +if test -z "${DEFAULT_TARGET_X32_TRUE}" && test -z "${DEFAULT_TARGET_X32_FALSE}"; then + as_fn_error "conditional \"DEFAULT_TARGET_X32\" was never defined. +Usually this means the macro was only invoked conditionally." "$LINENO" 5 +fi if test -z "${DEFAULT_TARGET_TILEGX_TRUE}" && test -z "${DEFAULT_TARGET_TILEGX_FALSE}"; then as_fn_error "conditional \"DEFAULT_TARGET_TILEGX\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 diff --git a/gold/configure.ac b/gold/configure.ac index b5741538128..a2e58955a69 100644 --- a/gold/configure.ac +++ b/gold/configure.ac @@ -204,7 +204,20 @@ for targ in $target $canon_targets; do AM_CONDITIONAL(DEFAULT_TARGET_I386, test "$targ_obj" = "i386") AM_CONDITIONAL(DEFAULT_TARGET_POWERPC, test "$targ_obj" = "powerpc") AM_CONDITIONAL(DEFAULT_TARGET_SPARC, test "$targ_obj" = "sparc") - AM_CONDITIONAL(DEFAULT_TARGET_X86_64, test "$targ_obj" = "x86_64") + target_x86_64=no + target_x32=no + if test "$targ_obj" = "x86_64"; then + case "$target" in + x86_64*-linux-gnux32) + target_x32=yes + ;; + *) + target_x86_64=yes + ;; + esac + fi + AM_CONDITIONAL(DEFAULT_TARGET_X86_64, test "$target_x86_64" = "yes") + AM_CONDITIONAL(DEFAULT_TARGET_X32, test "$target_x32" = "yes") AM_CONDITIONAL(DEFAULT_TARGET_TILEGX, test "$targ_obj" = "tilegx") AM_CONDITIONAL(DEFAULT_TARGET_MIPS, test "$targ_obj" = "mips") DEFAULT_TARGET=${targ_obj} diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 7604282f16b..aca2a410d40 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -2484,6 +2484,43 @@ MOSTLYCLEANFILES += split_x86_64_1 split_x86_64_2 split_x86_64_3 \ endif DEFAULT_TARGET_X86_64 +if DEFAULT_TARGET_X32 + +check_SCRIPTS += split_x32.sh +check_DATA += split_x32_1.stdout split_x32_2.stdout \ + split_x32_3.stdout split_x32_4.stdout split_x32_r.stdout +SPLIT_DEFSYMS = --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 +split_x32_1.o: split_x32_1.s + $(TEST_AS) -o $@ $< +split_x32_2.o: split_x32_2.s + $(TEST_AS) -o $@ $< +split_x32_3.o: split_x32_3.s + $(TEST_AS) -o $@ $< +split_x32_4.o: split_x32_4.s + $(TEST_AS) -o $@ $< +split_x32_n.o: split_x32_n.s + $(TEST_AS) -o $@ $< +split_x32_1: split_x32_1.o split_x32_n.o ../ld-new + ../ld-new $(SPLIT_DEFSYMS) -o $@ split_x32_1.o split_x32_n.o +split_x32_1.stdout: split_x32_1 + $(TEST_OBJDUMP) -d $< > $@ +split_x32_2: split_x32_2.o split_x32_n.o ../ld-new + ../ld-new $(SPLIT_DEFSYMS) -o $@ split_x32_2.o split_x32_n.o +split_x32_2.stdout: split_x32_2 + $(TEST_OBJDUMP) -d $< > $@ +split_x32_3.stdout: split_x32_3.o split_x32_n.o ../ld-new + ../ld-new $(SPLIT_DEFSYMS) -o split_x32_3 split_x32_3.o split_x32_n.o > $@ 2>&1 || exit 0 +split_x32_4: split_x32_4.o split_x32_n.o ../ld-new + ../ld-new $(SPLIT_DEFSYMS) -o $@ split_x32_4.o split_x32_n.o +split_x32_4.stdout: split_x32_4 + $(TEST_OBJDUMP) -d $< > $@ +split_x32_r.stdout: split_x32_1.o split_x32_n.o ../ld-new + ../ld-new -r split_x32_1.o split_x32_n.o -o split_x32_r > $@ 2>&1 || exit 0 +MOSTLYCLEANFILES += split_x32_1 split_x32_2 split_x32_3 \ + split_x32_4 split_x32_r + +endif DEFAULT_TARGET_X32 + if DEFAULT_TARGET_ARM check_SCRIPTS += arm_abs_global.sh diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 1174399680b..d818570a67f 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -623,6 +623,13 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @DEFAULT_TARGET_X86_64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_83 = split_x86_64_1 split_x86_64_2 split_x86_64_3 \ @DEFAULT_TARGET_X86_64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_x86_64_4 split_x86_64_r +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_84 = split_x32.sh +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_85 = split_x32_1.stdout split_x32_2.stdout \ +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_x32_3.stdout split_x32_4.stdout split_x32_r.stdout + +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_86 = split_x32_1 split_x32_2 split_x32_3 \ +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_x32_4 split_x32_r + # ARM1176 workaround test. @@ -635,7 +642,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ # Check Thumb to Thumb farcall veneers # Check Thumb to ARM farcall veneers -@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_84 = arm_abs_global.sh \ +@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_87 = arm_abs_global.sh \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_branch_in_range.sh \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_branch_out_of_range.sh \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_fix_v4bx.sh \ @@ -649,7 +656,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_arm_thumb.sh \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_thumb.sh \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_arm.sh -@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_85 = arm_abs_global.stdout \ +@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_88 = arm_abs_global.stdout \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_bl_in_range.stdout \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_bl_out_of_range.stdout \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ thumb_bl_in_range.stdout \ @@ -694,7 +701,7 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_thumb_6m.stdout \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_arm.stdout \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_arm_5t.stdout -@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_86 = arm_abs_global \ +@DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_89 = arm_abs_global \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_bl_in_range \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_bl_out_of_range \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ thumb_bl_in_range \ @@ -737,10 +744,10 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_thumb_6m \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_arm \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_farcall_thumb_arm_5t -@DEFAULT_TARGET_X86_64_TRUE@am__append_87 = *.dwo *.dwp -@DEFAULT_TARGET_X86_64_TRUE@am__append_88 = dwp_test_1.sh \ +@DEFAULT_TARGET_X86_64_TRUE@am__append_90 = *.dwo *.dwp +@DEFAULT_TARGET_X86_64_TRUE@am__append_91 = dwp_test_1.sh \ @DEFAULT_TARGET_X86_64_TRUE@ dwp_test_2.sh -@DEFAULT_TARGET_X86_64_TRUE@am__append_89 = dwp_test_1.stdout \ +@DEFAULT_TARGET_X86_64_TRUE@am__append_92 = dwp_test_1.stdout \ @DEFAULT_TARGET_X86_64_TRUE@ dwp_test_2.stdout subdir = testsuite DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am @@ -2223,7 +2230,8 @@ MOSTLYCLEANFILES = *.so *.syms *.stdout $(am__append_4) \ $(am__append_41) $(am__append_47) $(am__append_63) \ $(am__append_66) $(am__append_69) $(am__append_72) \ $(am__append_74) $(am__append_77) $(am__append_80) \ - $(am__append_83) $(am__append_86) $(am__append_87) + $(am__append_83) $(am__append_86) $(am__append_89) \ + $(am__append_90) # We will add to these later, for each individual test. Note # that we add each test under check_SCRIPTS or check_PROGRAMS; @@ -2232,13 +2240,13 @@ check_SCRIPTS = $(am__append_2) $(am__append_34) $(am__append_38) \ $(am__append_42) $(am__append_45) $(am__append_61) \ $(am__append_64) $(am__append_67) $(am__append_70) \ $(am__append_75) $(am__append_78) $(am__append_81) \ - $(am__append_84) $(am__append_88) + $(am__append_84) $(am__append_87) $(am__append_91) check_DATA = $(am__append_3) $(am__append_27) $(am__append_29) \ $(am__append_35) $(am__append_39) $(am__append_43) \ $(am__append_46) $(am__append_62) $(am__append_65) \ $(am__append_68) $(am__append_71) $(am__append_76) \ $(am__append_79) $(am__append_82) $(am__append_85) \ - $(am__append_89) + $(am__append_88) $(am__append_92) BUILT_SOURCES = $(am__append_25) TESTS = $(check_SCRIPTS) $(check_PROGRAMS) @@ -2736,6 +2744,7 @@ LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL) \ @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@exception_x86_64_bnd_test_LDFLAGS = $(exception_test_LDFLAGS) @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@exception_x86_64_bnd_test_LDADD = exception_x86_64_bnd_1.o exception_x86_64_bnd_2.o @DEFAULT_TARGET_I386_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@SPLIT_DEFSYMS = --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@SPLIT_DEFSYMS = --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 @DEFAULT_TARGET_X86_64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@SPLIT_DEFSYMS = --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am @@ -4180,6 +4189,8 @@ split_i386.sh.log: split_i386.sh @p='split_i386.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) split_x86_64.sh.log: split_x86_64.sh @p='split_x86_64.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) +split_x32.sh.log: split_x32.sh + @p='split_x32.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) arm_abs_global.sh.log: arm_abs_global.sh @p='arm_abs_global.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) arm_branch_in_range.sh.log: arm_branch_in_range.sh @@ -5791,6 +5802,32 @@ uninstall-am: @DEFAULT_TARGET_X86_64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -d $< > $@ @DEFAULT_TARGET_X86_64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x86_64_r.stdout: split_x86_64_1.o split_x86_64_n.o ../ld-new @DEFAULT_TARGET_X86_64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new -r split_x86_64_1.o split_x86_64_n.o -o split_x86_64_r > $@ 2>&1 || exit 0 +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_1.o: split_x32_1.s +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_2.o: split_x32_2.s +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_3.o: split_x32_3.s +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_4.o: split_x32_4.s +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_n.o: split_x32_n.s +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_1: split_x32_1.o split_x32_n.o ../ld-new +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new $(SPLIT_DEFSYMS) -o $@ split_x32_1.o split_x32_n.o +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_1.stdout: split_x32_1 +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -d $< > $@ +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_2: split_x32_2.o split_x32_n.o ../ld-new +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new $(SPLIT_DEFSYMS) -o $@ split_x32_2.o split_x32_n.o +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_2.stdout: split_x32_2 +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -d $< > $@ +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_3.stdout: split_x32_3.o split_x32_n.o ../ld-new +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new $(SPLIT_DEFSYMS) -o split_x32_3 split_x32_3.o split_x32_n.o > $@ 2>&1 || exit 0 +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_4: split_x32_4.o split_x32_n.o ../ld-new +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new $(SPLIT_DEFSYMS) -o $@ split_x32_4.o split_x32_n.o +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_4.stdout: split_x32_4 +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -d $< > $@ +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_x32_r.stdout: split_x32_1.o split_x32_n.o ../ld-new +@DEFAULT_TARGET_X32_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new -r split_x32_1.o split_x32_n.o -o split_x32_r > $@ 2>&1 || exit 0 @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@arm_abs_lib.o: arm_abs_lib.s @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -march=armv7-a -o $@ $< @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@libarm_abs.so: arm_abs_lib.o ../ld-new diff --git a/gold/testsuite/split_x32.sh b/gold/testsuite/split_x32.sh new file mode 100755 index 00000000000..0bc0cf363cd --- /dev/null +++ b/gold/testsuite/split_x32.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +# split_x32.sh -- test -fstack-split for x32 + +# Copyright (C) 2014 Free Software Foundation, Inc. +# Written by Ian Lance Taylor <iant@google.com>. +# Modified by H.J. Lu <hongjiu.lu@intel.com>. + +# This file is part of gold. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +match() +{ + if ! egrep "$1" "$2" >/dev/null 2>&1; then + echo 1>&2 "could not find '$1' in $2" + exit 1 + fi +} + +nomatch() +{ + if egrep "$1" "$2" >/dev/null 2>&1; then + echo 1>&2 "found unexpected '$1' in $2" + exit 1 + fi +} + +match 'cmp.*+%fs:[^,]*,%esp' split_x32_1.stdout +match 'callq.*__morestack>?$' split_x32_1.stdout +match 'lea.*-0x200\(%rsp\),' split_x32_1.stdout + +match 'stc' split_x32_2.stdout +match 'callq.*__morestack_non_split>?$' split_x32_2.stdout +nomatch 'callq.*__morestack>?$' split_x32_2.stdout +match 'lea.*-0x4200\(%rsp\),' split_x32_2.stdout + +match 'failed to match' split_x32_3.stdout + +match 'callq.*__morestack>?$' split_x32_4.stdout + +match 'cannot mix' split_x32_r.stdout diff --git a/gold/testsuite/split_x32_1.s b/gold/testsuite/split_x32_1.s new file mode 100644 index 00000000000..b78936eb18e --- /dev/null +++ b/gold/testsuite/split_x32_1.s @@ -0,0 +1,33 @@ +# split_x32_1.s: x32 specific test case for -fsplit-stack. + + .text + + .global fn1 + .type fn1,@function +fn1: + cmp %fs:0x40,%esp + jae 1f + callq __morestack + retq +1: + callq fn2 + retq + + .size fn1,. - fn1 + + .global fn2 + .type fn2,@function +fn2: + lea -0x200(%rsp),%r10d + cmp %fs:0x40,%r10d + jae 1f + callq __morestack + retq +1: + callq fn1 + retq + + .size fn2,. - fn2 + + .section .note.GNU-stack,"",@progbits + .section .note.GNU-split-stack,"",@progbits diff --git a/gold/testsuite/split_x32_2.s b/gold/testsuite/split_x32_2.s new file mode 100644 index 00000000000..b789afd8a00 --- /dev/null +++ b/gold/testsuite/split_x32_2.s @@ -0,0 +1,33 @@ +# split_x32_2.s: x32 specific, -fsplit-stack calling non-split + + .text + + .global fn1 + .type fn1,@function +fn1: + cmp %fs:0x40,%esp + jae 1f + callq __morestack + retq +1: + callq fn3 + retq + + .size fn1,. - fn1 + + .global fn2 + .type fn2,@function +fn2: + lea -0x200(%rsp),%r10d + cmp %fs:0x40,%r10d + jae 1f + callq __morestack + retq +1: + callq fn3 + retq + + .size fn2,. - fn2 + + .section .note.GNU-stack,"",@progbits + .section .note.GNU-split-stack,"",@progbits diff --git a/gold/testsuite/split_x32_3.s b/gold/testsuite/split_x32_3.s new file mode 100644 index 00000000000..d7b09bdcda0 --- /dev/null +++ b/gold/testsuite/split_x32_3.s @@ -0,0 +1,22 @@ +# split_x32_3.s: x32 specific, adjustment failure + + .text + + .global fn1 + .type fn1,@function +fn1: + push %rbp + mov %esp,%ebp + cmp %fs:0x40,%esp + jae 1f + callq __morestack + retq +1: + callq fn3 + leaveq + retq + + .size fn1,. - fn1 + + .section .note.GNU-stack,"",@progbits + .section .note.GNU-split-stack,"",@progbits diff --git a/gold/testsuite/split_x32_4.s b/gold/testsuite/split_x32_4.s new file mode 100644 index 00000000000..1f4eece4a54 --- /dev/null +++ b/gold/testsuite/split_x32_4.s @@ -0,0 +1,23 @@ +# split_x32_4.s: x32 specific, permitted adjustment failure + + .text + + .global fn1 + .type fn1,@function +fn1: + push %rbp + mov %esp,%ebp + cmp %fs:0x40,%esp + jae 1f + callq __morestack + retq +1: + callq fn3 + leaveq + retq + + .size fn1,. - fn1 + + .section .note.GNU-stack,"",@progbits + .section .note.GNU-split-stack,"",@progbits + .section .note.GNU-no-split-stack,"",@progbits diff --git a/gold/testsuite/split_x32_n.s b/gold/testsuite/split_x32_n.s new file mode 100644 index 00000000000..54c0db69459 --- /dev/null +++ b/gold/testsuite/split_x32_n.s @@ -0,0 +1,12 @@ +# split_x32_n.s: x32 specific, -fsplit-stack calling non-split + + .text + + .global fn3 + .type fn3,@function +fn3: + retq + + .size fn3,. - fn3 + + .section .note.GNU-stack,"",@progbits diff --git a/gold/x86_64.cc b/gold/x86_64.cc index c368b039869..dd6c07b9516 100644 --- a/gold/x86_64.cc +++ b/gold/x86_64.cc @@ -4463,6 +4463,14 @@ Target_x86_64<size>::do_ehframe_datarel_base() const // code. We have to change the function so that it always ensures // that it has enough stack space to run some random function. +static const unsigned char cmp_insn_32[] = { 0x64, 0x3b, 0x24, 0x25 }; +static const unsigned char lea_r10_insn_32[] = { 0x44, 0x8d, 0x94, 0x24 }; +static const unsigned char lea_r11_insn_32[] = { 0x44, 0x8d, 0x9c, 0x24 }; + +static const unsigned char cmp_insn_64[] = { 0x64, 0x48, 0x3b, 0x24, 0x25 }; +static const unsigned char lea_r10_insn_64[] = { 0x4c, 0x8d, 0x94, 0x24 }; +static const unsigned char lea_r11_insn_64[] = { 0x4c, 0x8d, 0x9c, 0x24 }; + template<int size> void Target_x86_64<size>::do_calls_non_split(Relobj* object, unsigned int shndx, @@ -4473,25 +4481,40 @@ Target_x86_64<size>::do_calls_non_split(Relobj* object, unsigned int shndx, std::string* from, std::string* to) const { + const char* const cmp_insn = reinterpret_cast<const char*> + (size == 32 ? cmp_insn_32 : cmp_insn_64); + const char* const lea_r10_insn = reinterpret_cast<const char*> + (size == 32 ? lea_r10_insn_32 : lea_r10_insn_64); + const char* const lea_r11_insn = reinterpret_cast<const char*> + (size == 32 ? lea_r11_insn_32 : lea_r11_insn_64); + + const size_t cmp_insn_len = + (size == 32 ? sizeof(cmp_insn_32) : sizeof(cmp_insn_64)); + const size_t lea_r10_insn_len = + (size == 32 ? sizeof(lea_r10_insn_32) : sizeof(lea_r10_insn_64)); + const size_t lea_r11_insn_len = + (size == 32 ? sizeof(lea_r11_insn_32) : sizeof(lea_r11_insn_64)); + const size_t nop_len = (size == 32 ? 7 : 8); + // The function starts with a comparison of the stack pointer and a // field in the TCB. This is followed by a jump. // cmp %fs:NN,%rsp - if (this->match_view(view, view_size, fnoffset, "\x64\x48\x3b\x24\x25", 5) - && fnsize > 9) + if (this->match_view(view, view_size, fnoffset, cmp_insn, cmp_insn_len) + && fnsize > nop_len + 1) { // We will call __morestack if the carry flag is set after this // comparison. We turn the comparison into an stc instruction // and some nops. view[fnoffset] = '\xf9'; - this->set_view_to_nop(view, view_size, fnoffset + 1, 8); + this->set_view_to_nop(view, view_size, fnoffset + 1, nop_len); } // lea NN(%rsp),%r10 // lea NN(%rsp),%r11 else if ((this->match_view(view, view_size, fnoffset, - "\x4c\x8d\x94\x24", 4) + lea_r10_insn, lea_r10_insn_len) || this->match_view(view, view_size, fnoffset, - "\x4c\x8d\x9c\x24", 4)) + lea_r11_insn, lea_r11_insn_len)) && fnsize > 8) { // This is loading an offset from the stack pointer for a |