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] gold: aarch64 split stack support


Hi Adhemerval, thanks for working on this. Here are a few comments -

On Thu, Aug 3, 2017 at 10:35 PM, Cary Coutant <ccoutant@gmail.com> wrote:
> Han, can you take a look at this?
>
> https://sourceware.org/ml/binutils/2017-07/msg00362.html
>
> -cary
>
>
>
> ---------- Forwarded message ----------
> From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> Date: Mon, Jul 31, 2017 at 12:03 PM
> Subject: [PATCH] gold: aarch64 split stack support
> To: binutils@sourceware.org
>
>
> This patch adds gold support for split-stack function calling non-split
> function on aarch64 following current proposal idea [1] [2].
>
> gold/ChangeLog:
>
>         * gold/aarch64.c (AArch64_insn_utilities::aarch64_movn_decode_imm):
>         New function.
>         (AArch64_insn_utilities::aarch64_movk_decode_imm): Likewise.
>         (AArch64_insn_utilities::clz_hwi): Likewise.
>         (AArch64_insn_utilities::aarch64_bitmask_imm): Likewise.
>         (Target_aarch64::do_calls_non_split): Likewise.
>         * gold/testsuite/Makefile.am [DEFAULT_TARGET_AARCH64] (check_SCRIPTS):
>         add split_aarch64.sh.
>         [DEFAULT_TARGET_AARCH64] (check_DATA): Add split_aarch64_{1,2,3,4,r)
>         tests.
>         [DEFAULT_TARGET_AARCH64] (SPLIT_DEFSYMS): New rule.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_1.o): Likewise.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_2.o): Likewise.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_3.o): Likewise.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_4.o): Likewise.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_r.o): Likewise.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_n.o): Likewise.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_1): Likewise.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_2): Likewise.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_2.stdout): Likewise.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_3.stdout): Likewise.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_4): Likewise.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_4.stdout): Likewise.
>         [DEFAULT_TARGET_AARCH64] (split_aarch64_r.stdout): Likewise.
>         [DEFAULT_TARGET_AARCH64] (MOSTLYCLEANFILES): Likewise.
>         * gold/testsuite/split_aarch64.sh: New file.
>         * gold/testsuite/split_aarch64_1.s: Likewise.
>         * gold/testsuite/split_aarch64_2.s: Likewise.
>         * gold/testsuite/split_aarch64_3.s: Likewise.
>         * gold/testsuite/split_aarch64_4.s: Likewise.
>         * gold/testsuite/split_aarch64_n.s: Likewise.
>
> [1] https://gcc.gnu.org/ml/gcc-patches/2017-07/msg01717.html
> [2] https://sourceware.org/ml/libc-alpha/2017-02/msg00272.html
> ---
>  gold/ChangeLog                   |  34 +++++++
>  gold/aarch64.cc                  | 213 ++++++++++++++++++++++++++++++++++++++-
>  gold/testsuite/Makefile.am       |  37 ++++++-
>  gold/testsuite/Makefile.in       |  40 +++++++-
>  gold/testsuite/split_aarch64.sh  |  59 +++++++++++
>  gold/testsuite/split_aarch64_1.s |  45 +++++++++
>  gold/testsuite/split_aarch64_2.s |  81 +++++++++++++++
>  gold/testsuite/split_aarch64_3.s |  24 +++++
>  gold/testsuite/split_aarch64_n.s |  12 +++
>  9 files changed, 538 insertions(+), 7 deletions(-)
>  create mode 100755 gold/testsuite/split_aarch64.sh
>  create mode 100644 gold/testsuite/split_aarch64_1.s
>  create mode 100644 gold/testsuite/split_aarch64_2.s
>  create mode 100644 gold/testsuite/split_aarch64_3.s
>  create mode 100644 gold/testsuite/split_aarch64_n.s
>
> diff --git a/gold/aarch64.cc b/gold/aarch64.cc
> index 58c7449..8220a45 100644
> --- a/gold/aarch64.cc
> +++ b/gold/aarch64.cc
> @@ -69,7 +69,7 @@ class AArch64_relocate_functions;
>
>  // Utility class dealing with insns. This is ported from macros in
>  // bfd/elfnn-aarch64.cc, but wrapped inside a class as static members. This
> -// class is used in erratum sequence scanning.
> +// class is used in erratum sequence scanning and split-stack calls.
>
>  template<bool big_endian>
>  class AArch64_insn_utilities
> @@ -167,6 +167,98 @@ public:
>      return ((((uint64_t)(1) << 32) - msbt) << 33) | value;
>    }
>
> +  // Retrieve encoded movn 64-bit signed imm value (64-bit variant only).
> +  static int64_t
> +  aarch64_movn_decode_imm(const Insntype movn)
> +  {
> +    int64_t imm = (movn & 0x1fffe0) >> 5;
> +    int hw = ((movn & 0x600000) >> 21) << 4;
> +    return imm << hw;
> +  }
> +
> +  // Retrieve encoded movk 64-bit signed imm value updating and existent value
> +  // (64-bit variant only).
> +  static int64_t
> +  aarch64_movk_decode_imm(const Insntype movk, int64_t value)
> +  {
> +    int64_t imm = (movk & 0x1FFFE0) >> 5;
> +    int hw = ((movk & 0x600000) >> 21) << 4;
> +    int64_t ret = imm << hw;
> +    int64_t mask = 0xffff << hw;
> +    return value ^ ((value ^ ret) & mask);
> +  }
> +
> +  // Return true if val is an immediate that can be loaded into a
> +  // register by a MOVZ instruction.
> +  static bool
> +  aarch64_movw_imm (int64_t val)
> +  {
> +    return ((val & 0xffffl) == val)
> +            || ((val & (0xffffl << 16)) == val)
> +            || ((val & (0xffffl << 32)) == val)
> +            || ((val & (0xffffl << 48)) == val);
> +  }
> +
> +  // For convenience, define 0 -> word_size.
> +  static inline int
> +  clz_hwi (uint64_t x)
> +  {
> +    if (x == 0)
> +      return 64;
> +    return __builtin_clzl (x);
> +  }
> +
> +  // Return true if val is a valid bitmask immediate.
> +  static bool
> +  aarch64_bitmask_imm (int64_t val_in)
> +  {
> +    static const uint64_t bitmask_imm_mul[] =
> +      {
> +       0x0000000100000001ull,
> +       0x0001000100010001ull,
> +       0x0101010101010101ull,
> +       0x1111111111111111ull,
> +       0x5555555555555555ull,
> +      };
> +    uint64_t val, tmp, mask, first_one, next_one;
> +    int bits;
> +
> +    // Check for a single sequence of one bits and return quickly if so.
> +    // The special cases of all ones and all zeroes returns false.
> +    val = (uint64_t) val_in;
> +    tmp = val + (val & -val);
> +
> +    if (tmp == (tmp & -tmp))
> +      return (val + 1) > 1;
> +
> +    // Invert if the immediate doesn't start with a zero bit - this means we
> +    // only need to search for sequences of one bits.
> +    if (val & 1)
> +      val = ~val;
> +
> +    // Find the first set bit and set tmp to val with the first sequence of
> +    // one bits removed.  Return success if there is a single sequence of
> +    // ones.
> +    first_one = val & -val;
> +    tmp = val & (val + first_one);
> +
> +    if (tmp == 0)
> +      return true;
> +
> +    // Find the next set bit and compute the difference in bit position.
> +    next_one = tmp & -tmp;
> +    bits = clz_hwi (first_one) - clz_hwi (next_one);
> +    mask = val ^ tmp;
> +
> +    // Check the bit position difference is a power of 2, and that the first
> +    // sequence of one bits fits within 'bits' bits.
> +    if ((mask >> bits) != 0 || bits != (bits & -bits))
> +      return false;
> +
> +    // Check the sequence of one bits is repeated 64/bits times.
> +    return val == mask * bitmask_imm_mul[__builtin_clz (bits) - 26];
> +  }
> +
>    static bool
>    aarch64_b(const Insntype insn)
>    { return (insn & 0xFC000000) == 0x14000000; }
> @@ -3009,6 +3101,14 @@ class Target_aarch64 : public
> Sized_target<size, big_endian>
>    do_can_check_for_function_pointers() const
>    { return true; }
>
> +  // Adjust -fsplit-stack code which calls non-split-stack code.
> +  void
> +  do_calls_non_split(Relobj* object, unsigned int shndx,
> +                    section_offset_type fnoffset, section_size_type fnsize,
> +                    const unsigned char* prelocs, size_t reloc_count,
> +                    unsigned char* view, section_size_type view_size,
> +                    std::string* from, std::string* to) const;
> +
>    // Return the number of entries in the PLT.
>    unsigned int
>    plt_entry_count() const;
> @@ -6799,6 +6899,117 @@ Target_aarch64<size, big_endian>::gc_process_relocs(
>      plocal_symbols);
>  }
>
> +// FNOFFSET in section SHNDX in OBJECT is the start of a function
> +// compiled with -fsplit-stack.  The function calls non-split-stack
> +// code.  Change the function to ensure it has enough stack space to
> +// call some random function.
> +
> +template<int size, bool big_endian>
> +void
> +Target_aarch64<size, big_endian>::do_calls_non_split(
> +    Relobj* object,
> +    unsigned int shndx,
> +    section_offset_type fnoffset,
> +    section_size_type fnsize,
> +    const unsigned char* prelocs,
> +    size_t reloc_count,
> +    unsigned char* view,
> +    section_size_type view_size,
> +    std::string* from,
> +    std::string* to) const
> +{
> +  // 32-bit not supported.
> +  if (size == 32)
> +    {
> +      // warn
> +      Target::do_calls_non_split(object, shndx, fnoffset, fnsize,
> +                                prelocs, reloc_count, view, view_size,
> +                                from, to);
> +      return;
> +    }
> +
> +  // The function starts with:
> +  // mrs    x9, tpidr_el0
> +  // mov    x10, <required stack allocation>
> +  // movk   x10, #0x0, lsl #16
> +  // sub    x10, sp, x10
> +  // mov    x11, sp          # if function has stacked arguments
> +  // adrp   x12, main_fn_entry
> +  // add    x12, x12, :lo12:.L2
> +  // cmp    x9, x10
> +
> +  unsigned char *entry = view + fnoffset;
> +  unsigned char *pinsn = entry;
> +  bool ok = false;
> +
> +  unsigned char *pmov = 0, *pmovk = 0;
> +  const uint32_t mov_mask = 0xff80001f; // ignore 'hw' bits.
> +  const uint32_t mrs_x9_tp = 0xd53bd049;
> +  const uint32_t movz_x10_imm = 0xd280000a;
> +  const uint32_t movk_x10_imm = 0xf280000a;
> +  const uint32_t sub_x10_sp_x10 = 0xcb2a63ea;
> +
> +  uint32_t insn = elfcpp::Swap<32, big_endian>::readval(entry);
> +  if (insn == mrs_x9_tp)
> +    {
> +      int64_t allocate = 0;
> +      while (1)
> +       {

This seems a little bit fragile to me - what if a function starts with
insn "mrs x9, tpidr_el0", but the rest of the function does not match
the rest of the pattern (for example, in a hand-written asm file),
this would lead to a loop that never ends.

> +         pinsn += 4;
> +         insn = elfcpp::Swap<32, big_endian>::readval(pinsn);
> +         if ((insn & mov_mask) == movz_x10_imm)
> +           {
> +             pmov = pinsn;
> +             allocate = Insn_utilities::aarch64_movn_decode_imm(insn);
> +           }
> +         else if ((insn & mov_mask) == movk_x10_imm)
> +           {
> +             pmovk = pinsn;
> +             allocate = Insn_utilities::aarch64_movk_decode_imm(insn,
> allocate);
> +           }
> +         else if (insn == sub_x10_sp_x10)
> +           break;

This is the only loop exit, but we may never find "sub_x10_sp_x10"
insn in some hand written code.

> +       }
> +
> +      gold_assert(pmov);
> +      gold_assert(pmovk);
> +
> +      if (insn == sub_x10_sp_x10)

When control flow reaches here, insn always equals to sub_x10_sp_x10.

> +       {
> +         int extra = parameters->options().split_stack_adjust_size();
> +         allocate += extra;
> +         if (allocate >= ((int64_t)1 << 32) || extra < 0)
> +           {
> +             object->error(_("split-stack stack size overflow at "
> +                             "section %u offset %0zx"),
> +                           shndx, static_cast<size_t>(fnoffset));
> +             return;
> +           }
> +
> +         insn = movz_x10_imm | ((allocate & 0xffff) << 5);
> +         elfcpp::Swap<32, big_endian>::writeval(pmov, insn);
> +         insn = movk_x10_imm | (((allocate >> 16) & 0xffff) << 5);
> +         insn |= 0x200000; // Set 'hw' bits to 01 to shift imm 16 bits.
> +         elfcpp::Swap<32, big_endian>::writeval(pmovk, insn);
> +         ok = true;
> +        }
> +    }
> +
> +  if (!ok)
> +    {
> +      if (!object->has_no_split_stack())
> +       object->error(_("failed to match split-stack sequence at "
> +                       "section %u offset %0zx"),
> +                     shndx, static_cast<size_t>(fnoffset));
> +    }
> +
> +  // We have to change the function so that it calls
> +  // __morestack_non_split instead of __morestack.  The former will
> +  // allocate additional stack space.
> +  *from = "__morestack";
> +  *to = "__morestack_non_split";
> +}
> +
>  // Scan relocations for a section.
>
>  template<int size, bool big_endian>
> diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am
> index 26ee77a..8bcd198 100644
> --- a/gold/testsuite/Makefile.am
> +++ b/gold/testsuite/Makefile.am
> @@ -3794,16 +3794,45 @@ endif DEFAULT_TARGET_ARM
>
>  if DEFAULT_TARGET_AARCH64
>
> -check_SCRIPTS += aarch64_reloc_none.sh
> -check_DATA += aarch64_reloc_none.stdout
> +check_SCRIPTS += aarch64_reloc_none.sh split_aarch64.sh
> +check_DATA += aarch64_reloc_none.stdout split_aarch64_1.stdout \
> +       split_aarch64_2.stdout split_aarch64_3.stdout split_aarch64_4.stdout \
> +       split_aarch64_r.stdout
>  aarch64_reloc_none.o: aarch64_reloc_none.s
>         $(TEST_AS) -o $@ $<
>  aarch64_reloc_none: aarch64_reloc_none.o ../ld-new
>         ../ld-new -o $@ aarch64_reloc_none.o --gc-sections
>  aarch64_reloc_none.stdout: aarch64_reloc_none
>         $(TEST_NM) $< > $@
> -
> -MOSTLYCLEANFILES += aarch64_reloc_none
> +SPLIT_DEFSYMS = --defsym __morestack=0x100 --defsym __morestack_non_split=0x200
> +split_aarch64_1.o: split_aarch64_1.s
> +       $(TEST_AS) -o $@ $<
> +split_aarch64_2.o: split_aarch64_2.s
> +       $(TEST_AS) -o $@ $<
> +split_aarch64_3.o: split_aarch64_3.s
> +       $(TEST_AS) -o $@ $<
> +split_aarch64_4.o: split_aarch64_4.s
> +       $(TEST_AS) -o $@ $<
> +split_aarch64_n.o: split_aarch64_n.s
> +       $(TEST_AS) -o $@ $<
> +split_aarch64_1: split_aarch64_1.o ../ld-new
> +       ../ld-new $(SPLIT_DEFSYMS) -o $@ split_aarch64_1.o
> +split_aarch64_1.stdout: split_aarch64_1
> +       $(TEST_OBJDUMP) -d $< > $@
> +split_aarch64_2: split_aarch64_2.o split_aarch64_n.o ../ld-new
> +       ../ld-new $(SPLIT_DEFSYMS) -o $@ split_aarch64_2.o split_aarch64_n.o
> +split_aarch64_2.stdout: split_aarch64_2
> +       $(TEST_OBJDUMP) -d $< > $@
> +split_aarch64_3.stdout: split_aarch64_3.o split_aarch64_n.o ../ld-new
> +       ../ld-new $(SPLIT_DEFSYMS) -o split_aarch64_3
> split_aarch64_3.o split_aarch64_n.o > $@ 2>&1 || exit 0
> +split_aarch64_4: split_aarch64_4.o split_aarch64_n.o ../ld-new
> +       ../ld-new $(SPLIT_DEFSYMS) -o $@ split_aarch64_4.o split_aarch64_n.o
> +split_aarch64_4.stdout: split_aarch64_4
> +       $(TEST_OBJDUMP) -d $< > $@
> +split_aarch64_r.stdout: split_aarch64_1.o split_aarch64_n.o ../ld-new
> +       ../ld-new -r split_aarch64_1.o split_aarch64_n.o -o
> split_aarch64_r > $@ 2>&1 || exit 0
> +#MOSTLYCLEANFILES += aarch64_reloc_none split_aarch64_1 split_aarch64_2 \
> +       split_aarch64_3 split_aarch64_r
>
>  check_SCRIPTS += aarch64_relocs.sh
>  check_DATA += aarch64_relocs.stdout
> diff --git a/gold/testsuite/split_aarch64.sh b/gold/testsuite/split_aarch64.sh
> new file mode 100755
> index 0000000..7d12c88
> --- /dev/null
> +++ b/gold/testsuite/split_aarch64.sh
> @@ -0,0 +1,59 @@
> +#!/bin/sh
> +
> +# split_aarch64.sh -- test -fstack-split for AArch64
> +
> +# Copyright (C) 2009-2017 Free Software Foundation, Inc.
> +
> +# 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 'mov.*+x10,.#0x0( |$)' split_aarch64_1.stdout
> +match 'mov.*+x10,.#0x0,.lsl.#16( |$)' split_aarch64_1.stdout
> +match 'b.*__morestack>?$' split_aarch64_1.stdout
> +
> +match 'mov.*+x10,.#0x4000( |$)' split_aarch64_2.stdout
> +match 'mov.*+x10,.#0x0,.lsl.#16( |$)' split_aarch64_2.stdout
> +match 'b.*__morestack_non_split>?$' split_aarch64_2.stdout
> +match 'mov.*+x10,.#0x4210( |$)' split_aarch64_2.stdout
> +match 'mov.*+x10,.#0x0,.lsl.#16( |$)' split_aarch64_2.stdout
> +match 'b.*__morestack_non_split>?$' split_aarch64_2.stdout
> +match 'mov.*+x10,.#0x4110( |$)' split_aarch64_2.stdout
> +match 'mov.*+x10,.#0x1,.lsl.#16( |$)' split_aarch64_2.stdout
> +match 'b.*__morestack_non_split>?$' split_aarch64_2.stdout
> +
> +match 'failed to match' split_aarch64_3.stdout
> +
> +match 'mov.*+x10,.#0x4000( |$)' split_aarch64_4.stdout
> +match 'mov.*+x10,.#0x0,.lsl.#16( |$)' split_aarch64_4.stdout
> +
> +match 'cannot mix' split_aarch64_r.stdout
> diff --git a/gold/testsuite/split_aarch64_1.s b/gold/testsuite/split_aarch64_1.s
> new file mode 100644
> index 0000000..fd09987
> --- /dev/null
> +++ b/gold/testsuite/split_aarch64_1.s
> @@ -0,0 +1,45 @@
> +# split_aarch64_1.s: Split aware function calling each other, no need to
> +# adjust stack or change the morestack symbol call.
> +
> +       .text
> +
> +       .global fn1
> +       .type   fn1,@function
> +fn1:
> +       mrs     x9, tpidr_el0
> +       mov     x10, 0
> +       movk    x10, 0x0, lsl 16
> +       sub     x10, sp, x10
> +       adrp    x12, .L2
> +       add     x12, x12, :lo12:.L2
> +       ldr     x9, [x9, -8]
> +       cmp     x9, x10
> +       blt     .Lbcond4
> +       b       __morestack
> +.Lbcond4:
> +.L2:
> +       b       fn2
> +       .size   fn1,. - fn1
> +
> +       .global fn2
> +       .type   fn2,@function
> +fn2:
> +       mrs     x9, tpidr_el0
> +       mov     x10, 528
> +       movk    x10, 0x0, lsl 16
> +       sub     x10, sp, x10
> +       adrp    x12, .L3
> +       add     x12, x12, :lo12:.L3
> +       ldr     x9, [x9, -8]
> +       cmp     x9, x10
> +       blt     .Lbcond5
> +       b       __morestack
> +.Lbcond5:
> +.L3:
> +       bl      fn1
> +       ret
> +
> +       .size   fn2,. - fn2
> +
> +       .section        .note.GNU-stack,"",@progbits
> +       .section        .note.GNU-split-stack,"",@progbits
> diff --git a/gold/testsuite/split_aarch64_2.s b/gold/testsuite/split_aarch64_2.s
> new file mode 100644
> index 0000000..9819d43
> --- /dev/null
> +++ b/gold/testsuite/split_aarch64_2.s
> @@ -0,0 +1,81 @@
> +# split_aarch64_2.s: Split aware function calling non-split.
> +
> +       .text
> +
> +       .global fn1
> +       .type   fn1,@function
> +fn1:
> +       mrs     x9, tpidr_el0
> +       mov     x10, 0
> +       movk    x10, 0x0, lsl 16
> +       sub     x10, sp, x10
> +       adrp    x12, .L2
> +       add     x12, x12, :lo12:.L2
> +       ldr     x9, [x9, -8]
> +       cmp     x9, x10
> +       blt     .Lbcond4
> +       b       __morestack
> +.Lbcond4:
> +.L2:
> +       b       fnn
> +       .size   fn1,. - fn1
> +
> +       .global fn2
> +       .type   fn2,@function
> +fn2:
> +       mrs     x9, tpidr_el0
> +       mov     x10, 528
> +       movk    x10, 0x0, lsl 16
> +       sub     x10, sp, x10
> +       adrp    x12, .L6
> +       add     x12, x12, :lo12:.L6
> +       ldr     x9, [x9, -8]
> +       cmp     x9, x10
> +       blt     .Lbcond8
> +       b       __morestack
> +.Lbcond8:
> +.L6:
> +       bl      fnn
> +       ret
> +       .size   fn2,. - fn2
> +
> +       .global fn3
> +       .type   fn3,@function
> +fn3:
> +        mrs     x9, tpidr_el0
> +        mov     x10, 272
> +        movk    x10, 0x1, lsl 16
> +        sub     x10, sp, x10
> +        adrp    x12, .L10
> +        add     x12, x12, :lo12:.L10
> +        ldr     x9, [x9, -8]
> +        cmp     x9, x10
> +        blt     .Lbcond12
> +        b       __morestack
> +.Lbcond12:
> +.L10:
> +        bl      fnn
> +        ret
> +        .size   fn3, .-fn3
> +
> +       .global fn4
> +       .type   fn4,@function
> +fn4:
> +        mrs     x9, tpidr_el0
> +        mov     x10, 65520
> +        movk    x10, 0x1, lsl 16
> +        sub     x10, sp, x10
> +        adrp    x12, .L14
> +        add     x12, x12, :lo12:.L14
> +        ldr     x9, [x9, -8]
> +        cmp     x9, x10
> +        blt     .Lbcond16
> +        b       __morestack
> +.Lbcond16:
> +.L14:
> +        bl      fnn
> +        ret
> +        .size   fn4, .-fn4
> +
> +       .section        .note.GNU-stack,"",@progbits
> +       .section        .note.GNU-split-stack,"",@progbits
> diff --git a/gold/testsuite/split_aarch64_3.s b/gold/testsuite/split_aarch64_3.s
> new file mode 100644
> index 0000000..c32db61
> --- /dev/null
> +++ b/gold/testsuite/split_aarch64_3.s
> @@ -0,0 +1,24 @@
> +# split_aarch64_3.s: Missing initial thread-pointer get instruction.
> +
> +       .text
> +
> +       .global fn1
> +       .type   fn1,@function
> +fn1:
> +       mov     x10, 0
> +       movk    x10, 0x0, lsl 16
> +       sub     x10, sp, x10
> +       adrp    x12, .L2
> +       add     x12, x12, :lo12:.L2
> +       ldr     x9, [x9, -8]
> +       cmp     x9, x10
> +       blt     .Lbcond4
> +       b       __morestack
> +.Lbcond4:
> +.L2:
> +       b       fnn
> +
> +       .size   fn1,. - fn1
> +
> +       .section        .note.GNU-stack,"",@progbits
> +       .section        .note.GNU-split-stack,"",@progbits
> diff --git a/gold/testsuite/split_aarch64_n.s b/gold/testsuite/split_aarch64_n.s
> new file mode 100644
> index 0000000..31c29cf
> --- /dev/null
> +++ b/gold/testsuite/split_aarch64_n.s
> @@ -0,0 +1,12 @@
> +# split_aarch64_n.s: AArch64 specific, -fsplit-stack calling non-split
> +
> +       .text
> +
> +       .global fnn
> +       .type   fnn,@function
> +fnn:
> +       ret
> +
> +       .size   fnn,. - fnn
> +
> +       .section        .note.GNU-stack,"",@progbits
> --
> 2.7.4



-- 
Han Shen |  Software Engineer |  shenhan@google.com |  +1-650-440-3330


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