This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] PR gold/17729: [gold] gold failed to build x32 libgo


On Tue, Jan 6, 2015 at 3:18 PM, Cary Coutant <ccoutant@google.com> wrote:
>> +  if (size == 32)
>> +    {
>> +      // For X32
>> +      // cmp %fs:NN,%esp
>> +      cmp_insn = "\x64\x3b\x24\x25";
>> +      cmp_insn_len = 4;
>> +      // lea NN(%rsp),%r10d
>> +      // lea NN(%rsp),%r11d
>> +      lea_r10_insn = "\x44\x8d\x94\x24";
>> +      lea_r11_insn = "\x44\x8d\x9c\x24";
>> +      nop_insn_len = 7;
>> +    }
>> ...
>
> The rest of this patch is OK, but in do_calls_non_split(), I'd prefer
> something like this (note also the depedency between nop_size and the
> test against fnsize for the cmp instruction):
>
> --- a/gold/x86_64.cc
> +++ b/gold/x86_64.cc
> @@ -4457,6 +4457,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,
> @@ -4467,25 +4475,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

This is what I checked in.  I'd like to backport it to 2.25 branch.
OK for 2.25 branch?

Thanks.

-- 
H.J.
From 4fc1b9d43cbce7571264a0011c87258b78252750 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 18 Dec 2014 11:09:28 -0800
Subject: [PATCH] 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.
---
 gold/ChangeLog               | 27 ++++++++++++++++++++++
 gold/configure               | 28 +++++++++++++++++++++-
 gold/configure.ac            | 15 +++++++++++-
 gold/testsuite/Makefile.am   | 37 +++++++++++++++++++++++++++++
 gold/testsuite/Makefile.in   | 55 ++++++++++++++++++++++++++++++++++++--------
 gold/testsuite/split_x32.sh  | 55 ++++++++++++++++++++++++++++++++++++++++++++
 gold/testsuite/split_x32_1.s | 33 ++++++++++++++++++++++++++
 gold/testsuite/split_x32_2.s | 33 ++++++++++++++++++++++++++
 gold/testsuite/split_x32_3.s | 22 ++++++++++++++++++
 gold/testsuite/split_x32_4.s | 23 ++++++++++++++++++
 gold/testsuite/split_x32_n.s | 12 ++++++++++
 gold/x86_64.cc               | 33 ++++++++++++++++++++++----
 12 files changed, 357 insertions(+), 16 deletions(-)
 create mode 100755 gold/testsuite/split_x32.sh
 create mode 100644 gold/testsuite/split_x32_1.s
 create mode 100644 gold/testsuite/split_x32_2.s
 create mode 100644 gold/testsuite/split_x32_3.s
 create mode 100644 gold/testsuite/split_x32_4.s
 create mode 100644 gold/testsuite/split_x32_n.s

diff --git a/gold/ChangeLog b/gold/ChangeLog
index af56066..93529fe 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 7d7b849..23e4735 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 b574153..a2e5895 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 7604282..aca2a41 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 1174399..d818570 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 0000000..0bc0cf3
--- /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 0000000..b78936e
--- /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 0000000..b789afd
--- /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 0000000..d7b09bd
--- /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 0000000..1f4eece
--- /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 0000000..54c0db6
--- /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 c368b03..dd6c07b 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
-- 
1.9.3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]