From patchwork Wed Feb 7 18:01:44 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 127206 Delivered-To: patch@linaro.org Received: by 10.46.124.24 with SMTP id x24csp712991ljc; Wed, 7 Feb 2018 10:02:16 -0800 (PST) X-Google-Smtp-Source: AH8x227Kr+qTLcHh7R2l7Fj7zisbYaP+zKSG3Yr3GuHSRT7XbPsUyIm72Re05ep0yGRHoI+Ery5M X-Received: by 10.101.101.19 with SMTP id x19mr5742820pgv.347.1518026536806; Wed, 07 Feb 2018 10:02:16 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1518026536; cv=none; d=google.com; s=arc-20160816; b=xe3DGRbsMBrDtRQOZQrxAZT9KL3gaycNZG09trV//pNAxTVQSctqVKwGlSw/eySveN 6kPU7BUVM2C/TymeRgxg9PxgN28SrJcnbV7X56X84Kpp32S0jDCj+ycMzNBvnuIwE7Zy LdAO2OJBJE0dV7m4uUPusF4FUQQFZkU7Bizq4SzXvC0/4A4heyIM+Lc1GZdctNpUjdHF 7/q17CUAWb+UC2nDt0mtsGP0VJbKY3ulm43ycl1yU22jcLAiVJcItPNUK5ikyVkYs8oj By4LMgJNIGKnQPq1nzmWqAJg7JDO6T28dGOJ8GJTDFSTjOkhUwCcEqLSVv4r4IJbLpEq 26JA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=message-id:date:subject:to:from:delivered-to:sender:list-help :list-post:list-archive:list-subscribe:list-unsubscribe:list-id :precedence:mailing-list:dkim-signature:domainkey-signature :arc-authentication-results; bh=4zMJuSUa8AH6MJbEssEj5PTqQ7M60jGHiE4nvK6Mc2U=; b=oqppwbCphZ3vVD74LVuRkfDBTHnOFKaAfgl5T26EP86fU1nMf2i+ILbgW6taMeOsNw c2GnnTz54gC0e7umRg4l5ei3b7iTMKJNXyFbzzOXU0Cc/046sVNO4ZeoRrlc7sHVFBvc BKNAKjiA09VokGkz3sbfrtq5GPeiVnnresxFc0ikaRv494Uw9wugPED0QmsaH/nnWixK ynYvvSXjkKec5nIN8cg2GyfPKWohjTO4veT0qSN3GqJVkBvuRUEW/VOHNrDEtHJaRtKh Ks0l6WjGEV7Y8ECx3ZcDRb3GGX+7eblVJvGqb7fWeei4wUilQQgbgIqkettTofPHCKIA txmQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=jwP/EVG2; spf=pass (google.com: domain of binutils-return-100370-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=binutils-return-100370-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id y124si1234739pgy.100.2018.02.07.10.02.16 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 07 Feb 2018 10:02:16 -0800 (PST) Received-SPF: pass (google.com: domain of binutils-return-100370-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org header.s=default header.b=jwP/EVG2; spf=pass (google.com: domain of binutils-return-100370-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=binutils-return-100370-patch=linaro.org@sourceware.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; q=dns; s= default; b=rd/n8vboaGyK0j5JXFyRZcNo3o+d2Ka5/M88Vpa0W6X2vWFQtkFv6 rDnKy7/iDPMpIISm7Z3qqCfPeApeaMPaxUZmHnROf8wOi+SRNIFL6zsgw8G1Ybd7 s0SAR9/c6ibDtxjxHsi4Zqo84/bkuZBu+Cnf3KsRbYtklfo7/neC0s= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id; s=default; bh=IpSyjUbQSZHf5rZK36Isgyd8x2g=; b=jwP/EVG28z9WrfYCGFW1Eghd16nW JiWd9K3zyMvlaTKrYFtkxmZKr0qfZWcZXt4pQCD0GBtfKNvfBWxKdMQmyuKmWjo5 pvaOfrzDsBwJwV/TI+hBA8QxzvbhdiHpG2m2s2skhm6F0lZ5ugJvWuTTq63Ez/mn JMJiL1x6Hl+f1zs= Received: (qmail 59183 invoked by alias); 7 Feb 2018 18:02:01 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Delivered-To: mailing list binutils@sourceware.org Received: (qmail 58812 invoked by uid 89); 7 Feb 2018 18:01:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-24.1 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS, UNSUBSCRIBE_BODY autolearn=ham version=3.3.2 spammy=Improved, ported X-HELO: mail-qk0-f173.google.com Received: from mail-qk0-f173.google.com (HELO mail-qk0-f173.google.com) (209.85.220.173) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 07 Feb 2018 18:01:54 +0000 Received: by mail-qk0-f173.google.com with SMTP id e20so2240248qkm.7 for ; Wed, 07 Feb 2018 10:01:53 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id; bh=4zMJuSUa8AH6MJbEssEj5PTqQ7M60jGHiE4nvK6Mc2U=; b=ZhfRv83lhxM/AzHztDApshnzlvYjQQ+N4m7jwiHkGpHp98DYlM3W3kilXSnCXRFrRU IlpmtRAZL0EFCxtVyJ4I1A9ot1ZMQ9DEpYiU4ju2J2tjD7GLpn+ZFWXDQkRJyd3oHVKC dgabJi++7JAcgzNBL/PGoP7QQrLT5ngTORAu/6jjYVtxEhzTBxOYmxhNHxdrq0zdpOfW fPPGQ27uGLeMnIKe1pYjOLyrELGSwCUh/DL0lmtfof53UzjmAWbGcxT982GVHDt5U9Y4 8wAKW9/Y1qpEc/y0xKyg0UxsbJz+MNF5z37g/Tuo2vK4szqVL7RwJhhsQv/j1xymbUBc ag1A== X-Gm-Message-State: APf1xPBqOyrXzVDmYj0h+FURVPCl6GTAaqxAZO0YHA9GKzwB6wJ5E7d4 5OvWpX+Ly/1NXg9hFCnrqX78ELIXWPs= X-Received: by 10.55.180.4 with SMTP id d4mr2518392qkf.242.1518026511649; Wed, 07 Feb 2018 10:01:51 -0800 (PST) Received: from localhost.localdomain ([179.159.9.95]) by smtp.googlemail.com with ESMTPSA id f125sm1370798qkd.58.2018.02.07.10.01.50 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 07 Feb 2018 10:01:50 -0800 (PST) From: Adhemerval Zanella To: binutils@sourceware.org Subject: [PATCH] gold: aarch64 split stack support Date: Wed, 7 Feb 2018 16:01:44 -0200 Message-Id: <1518026504-22473-1-git-send-email-adhemerval.zanella@linaro.org> X-IsSubscribed: yes Changes from previous version [1]: - Improved the loop to detect the split-stack prologue, now it should avoid unbound ending and fail malformatted instruction sequences. - Add split_aarch64_4 tests. -- This patch adds gold support for split-stack function calling non-split function on aarch64. 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://sourceware.org/ml/binutils/2017-07/msg00362.html --- gold/ChangeLog | 34 +++++++ gold/aarch64.cc | 212 ++++++++++++++++++++++++++++++++++++++- gold/testsuite/Makefile.am | 37 ++++++- gold/testsuite/Makefile.in | 40 +++++++- gold/testsuite/split_aarch64.sh | 60 +++++++++++ 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_4.s | 25 +++++ gold/testsuite/split_aarch64_n.s | 12 +++ 10 files changed, 563 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_4.s create mode 100644 gold/testsuite/split_aarch64_n.s -- 2.7.4 diff --git a/gold/aarch64.cc b/gold/aarch64.cc index 1abdb27..1b834d6 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 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; } @@ -3054,6 +3146,14 @@ class Target_aarch64 : public Sized_target 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; @@ -6844,6 +6944,116 @@ Target_aarch64::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 +void +Target_aarch64::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, + // movk x10, #0x0, lsl #16 + // sub x10, sp, x10 + // mov x11, sp # if function has stacked arguments + // mov x12, x30 + // ldur x9, [x9, #-8] + // cmp x9, x10 + + unsigned char *entry = view + fnoffset; + unsigned char *pinsn = entry; + bool ok = false; + + 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 cmp_x10_mask = 0xeb00015f; + const size_t max_insn = 8; + + uint32_t insn = elfcpp::Swap<32, big_endian>::readval(entry); + if (insn == mrs_x9_tp) + { + unsigned char *pmov = 0, *pmovk = 0; + int64_t allocate = 0; + /* Add an upper limit to handle ill formated headers. */ + for (size_t i = 0; i < max_insn; i++) + { + 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 & cmp_x10_mask) == cmp_x10_mask) + break; + } + + if (pmov != 0 && pmovk != 0) + { + 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(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(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 diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 16cae80..487f1f4 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -3875,16 +3875,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/Makefile.in b/gold/testsuite/Makefile.in index bbf8dc1..602e3ff 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -1012,16 +1012,23 @@ check_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) $(am__EXEEXT_3) \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_target2_abs \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_target2_got_rel \ @DEFAULT_TARGET_ARM_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ arm_target_lazy_init +#MOSTLYCLEANFILES += aarch64_reloc_none split_aarch64_1 split_aarch64_2 \ +# split_aarch64_3 split_aarch64_r @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_100 = aarch64_reloc_none.sh \ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_aarch64.sh \ @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ aarch64_relocs.sh \ @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ pr21430.sh \ @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ aarch64_tlsdesc.sh @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_101 = aarch64_reloc_none.stdout \ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_aarch64_1.stdout \ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_aarch64_2.stdout \ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_aarch64_3.stdout \ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_aarch64_4.stdout \ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ split_aarch64_r.stdout \ @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ aarch64_relocs.stdout \ @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ pr21430.stdout \ @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ aarch64_tlsdesc.stdout -@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_102 = aarch64_reloc_none \ -@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ aarch64_relocs \ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_102 = aarch64_relocs \ @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ pr21430 \ @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ aarch64_tlsdesc @DEFAULT_TARGET_S390_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@am__append_103 = split_s390.sh @@ -3438,6 +3445,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_DEPENDENCIES = gcctestdir/ld exception_x86_64_bnd_1.o exception_x86_64_bnd_2.o @DEFAULT_TARGET_X86_64_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@exception_x86_64_bnd_test_LDFLAGS = $(exception_test_LDFLAGS) -Wl,-z,bndplt @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_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@SPLIT_DEFSYMS = --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 @DEFAULT_TARGET_I386_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@SPLIT_DEFSYMS = --defsym __morestack=0x100 --defsym __morestack_non_split=0x200 @DEFAULT_TARGET_S390_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 @@ -5389,6 +5397,8 @@ arm_target2_got_rel.sh.log: arm_target2_got_rel.sh @p='arm_target2_got_rel.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) aarch64_reloc_none.sh.log: aarch64_reloc_none.sh @p='aarch64_reloc_none.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) +split_aarch64.sh.log: split_aarch64.sh + @p='split_aarch64.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) aarch64_relocs.sh.log: aarch64_relocs.sh @p='aarch64_relocs.sh'; $(am__check_pre) $(LOG_COMPILE) "$$tst" $(am__check_post) pr21430.sh.log: pr21430.sh @@ -7999,6 +8009,32 @@ uninstall-am: @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new -o $@ aarch64_reloc_none.o --gc-sections @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@aarch64_reloc_none.stdout: aarch64_reloc_none @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_NM) $< > $@ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_1.o: split_aarch64_1.s +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_2.o: split_aarch64_2.s +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_3.o: split_aarch64_3.s +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_4.o: split_aarch64_4.s +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_n.o: split_aarch64_n.s +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_1: split_aarch64_1.o ../ld-new +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new $(SPLIT_DEFSYMS) -o $@ split_aarch64_1.o +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_1.stdout: split_aarch64_1 +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -d $< > $@ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_2: split_aarch64_2.o split_aarch64_n.o ../ld-new +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new $(SPLIT_DEFSYMS) -o $@ split_aarch64_2.o split_aarch64_n.o +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_2.stdout: split_aarch64_2 +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -d $< > $@ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_3.stdout: split_aarch64_3.o split_aarch64_n.o ../ld-new +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new $(SPLIT_DEFSYMS) -o split_aarch64_3 split_aarch64_3.o split_aarch64_n.o > $@ 2>&1 || exit 0 +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_4: split_aarch64_4.o split_aarch64_n.o ../ld-new +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new $(SPLIT_DEFSYMS) -o $@ split_aarch64_4.o split_aarch64_n.o +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_4.stdout: split_aarch64_4 +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_OBJDUMP) -d $< > $@ +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@split_aarch64_r.stdout: split_aarch64_1.o split_aarch64_n.o ../ld-new +@DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ ../ld-new -r split_aarch64_1.o split_aarch64_n.o -o split_aarch64_r > $@ 2>&1 || exit 0 @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@aarch64_globals.o: aarch64_globals.s @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@ $(TEST_AS) -o $@ $< @DEFAULT_TARGET_AARCH64_TRUE@@NATIVE_OR_CROSS_LINKER_TRUE@aarch64_relocs.o: aarch64_relocs.s diff --git a/gold/testsuite/split_aarch64.sh b/gold/testsuite/split_aarch64.sh new file mode 100755 index 0000000..3b49ae6 --- /dev/null +++ b/gold/testsuite/split_aarch64.sh @@ -0,0 +1,60 @@ +#!/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,.#0x0( |$)' split_aarch64_4.stdout +match 'mov.*+x10,.#0x0,.lsl.#16( |$)' split_aarch64_4.stdout +match 'b.*__morestack_non_split>?$' split_aarch64_2.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_4.s b/gold/testsuite/split_aarch64_4.s new file mode 100644 index 0000000..f2988a5 --- /dev/null +++ b/gold/testsuite/split_aarch64_4.s @@ -0,0 +1,25 @@ +# split_aarch64_3.s: permitted adjustment failure + + .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 + .section .note.GNU-no-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