From patchwork Thu Dec 15 19:14:23 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 88220 Delivered-To: patch@linaro.org Received: by 10.140.20.101 with SMTP id 92csp979563qgi; Thu, 15 Dec 2016 11:14:53 -0800 (PST) X-Received: by 10.98.147.93 with SMTP id b90mr3745203pfe.170.1481829293237; Thu, 15 Dec 2016 11:14:53 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id p30si3844305pgd.213.2016.12.15.11.14.52 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Dec 2016 11:14:53 -0800 (PST) Received-SPF: pass (google.com: domain of libc-alpha-return-75948-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; spf=pass (google.com: domain of libc-alpha-return-75948-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=libc-alpha-return-75948-patch=linaro.org@sourceware.org; dmarc=fail (p=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=Yvo9pNc2Eo57RnTFm6MXZLiEvIBrnPGI5+KTtDuswzJiXOYfkjon1 HQLwIuQnFq17odw1hmjoOXhkREXKC9dHrhYqqtLH7gSeW+sP4mAZheBBLUaw415x hnnIwGqxqACqxL1oQbp7W/aopKJf5gfSxV9blTon6HXvwSpe+R/1Rg= 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=p7uHiXc3flYKw1vPI1m2UC8be2M=; b=Wgkp/8hF3ZvZ6pi5tRWlCFrmBaNE MbzB9y40RLX/UrrsR1lEagSfGO7nCFuG993GRi+Q0ffKAiVJj8YrWerYyrH7H81C buz3ev8yx2dv32+itOKFlyE9aX0CT30g9g3Ox2nFBIbIkWFvPI2v1JW4d9D4Pj0s scNG96kHYUBqS0o= Received: (qmail 71985 invoked by alias); 15 Dec 2016 19:14:43 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 71973 invoked by uid 89); 15 Dec 2016 19:14:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=cmpldi, r9r9r9, r6, r9, r7, r7, r6 X-HELO: mail-ua0-f171.google.com 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=ZnX0gt4U5/sWy8q0wTNfFpPTjeUCaLg7f6jS5uQ+Ymk=; b=k5uZFlEVssn21JUq34GVyTeLfH74Jyxahz73m8P4G4znr4PuuqEb/Ysexa9+d3m/Ff jKz1UOVS5ZJXyVPck0SWDwlr3jXmEGkWE8S16MpG7IWoNTQHp+9V9vYyLgFvQSvUoSK9 6gCTyTgppI7R1v5bySMNrytDKz1T/sPm1xchVbOtYxwB0lnGhyBLAn/eUbNPNT+VnJFV eStydokxIANnjzdLPgqtvc67zAIuOoaTRe3bm85aNQP9P6i0OjArRZo+309fu/M/T1Vk NmxW9Z1Ojnb7b0M6zm5GmaxW+TXjTU3J9xeqLXUTfkrxwlnV8mODacjHKqPJhRqea6px e+vg== X-Gm-Message-State: AKaTC03To0F+u0H7z3MJp50ijS75o8KiwKGEK7XWarNuTvOG4MlNJlMaOIcP6ug3JCgb8VyS X-Received: by 10.159.36.51 with SMTP id 48mr3802763uaq.27.1481829271188; Thu, 15 Dec 2016 11:14:31 -0800 (PST) From: Adhemerval Zanella To: libc-alpha@sourceware.org Subject: [PATCH v2] Fix powerpc64/power7 memchr for large input sizes Date: Thu, 15 Dec 2016 17:14:23 -0200 Message-Id: <1481829263-3740-1-git-send-email-adhemerval.zanella@linaro.org> Changes from previous version: - Add test-memchr.c SIZE_MAX tests. -- Current optimized powercp64/power7 memchr uses a strategy to check for p versus align(p+n) (where 'p' is the input char pointer and n the maximum size to check for the byte) without taking care for possible overflow on the pointer addition in case of large 'n'. It was triggered by 3038145ca23 where default rawmemchr (used to created ppc64 rawmemchr in ifunc selection) now uses memchr (p, c, (size_t)-1) on its implementation. This patch fixes it by implement a satured addition where overflows sets the maximum pointer size to UINTPTR_MAX. Checked on powerpc64le-linux-gnu. [BZ# 20971] * sysdeps/powerpc/powerpc64/power7/memchr.S (__memchr): Avoid overflow in pointer addition. * string/test-memchr.c (do_test): Add an argument to pass as the size on memchr. (test_main): Add check for SIZE_MAX. --- ChangeLog | 9 ++++++++ string/test-memchr.c | 38 +++++++++++++++++++++++-------- sysdeps/powerpc/powerpc64/power7/memchr.S | 12 +++++++++- 3 files changed, 49 insertions(+), 10 deletions(-) -- 2.7.4 diff --git a/string/test-memchr.c b/string/test-memchr.c index 449a19a..7431386 100644 --- a/string/test-memchr.c +++ b/string/test-memchr.c @@ -71,7 +71,7 @@ do_one_test (impl_t *impl, const CHAR *s, int c, size_t n, CHAR *exp_res) } static void -do_test (size_t align, size_t pos, size_t len, int seek_char) +do_test (size_t align, size_t pos, size_t len, size_t n, int seek_char) { size_t i; CHAR *result; @@ -103,7 +103,7 @@ do_test (size_t align, size_t pos, size_t len, int seek_char) } FOR_EACH_IMPL (impl, 0) - do_one_test (impl, (CHAR *) (buf + align), seek_char, len, result); + do_one_test (impl, (CHAR *) (buf + align), seek_char, n, result); } static void @@ -167,7 +167,7 @@ do_random_tests (void) int test_main (void) { - size_t i; + size_t i, j; test_init (); @@ -178,15 +178,35 @@ test_main (void) for (i = 1; i < 8; ++i) { - do_test (0, 16 << i, 2048, 23); - do_test (i, 64, 256, 23); - do_test (0, 16 << i, 2048, 0); - do_test (i, 64, 256, 0); + do_test (0, 16 << i, 2048, 2048, 23); + do_test (i, 64, 256, 256, 23); + do_test (0, 16 << i, 2048, 2048, 0); + do_test (i, 64, 256, 256, 0); + + /* Check for large input sizes and for these cases we need to + make sure the bye is within the size range (that's why + 7 << i must be smaller than 2048. */ + do_test (0, 7 << i, 2048, SIZE_MAX, 23); + do_test (0, 2048 - i, 2048, SIZE_MAX, 23); + do_test (i, 64, 256, SIZE_MAX, 23); + do_test (0, 7 << i, 2048, SIZE_MAX, 0); + do_test (0, 2048 - i, 2048, SIZE_MAX, 0); + do_test (i, 64, 256, SIZE_MAX, 0); } + + for (i = 1; i < 16; ++i) + { + for (j = 1; j < 16; j++) + { + do_test (0, 16 - j, 32, SIZE_MAX, 23); + do_test (i, 16 - j, 32, SIZE_MAX, 23); + } + } + for (i = 1; i < 32; ++i) { - do_test (0, i, i + 1, 23); - do_test (0, i, i + 1, 0); + do_test (0, i, i + 1, i + 1, 23); + do_test (0, i, i + 1, i + 1, 0); } do_random_tests (); diff --git a/sysdeps/powerpc/powerpc64/power7/memchr.S b/sysdeps/powerpc/powerpc64/power7/memchr.S index 03f0d7c..0737100 100644 --- a/sysdeps/powerpc/powerpc64/power7/memchr.S +++ b/sysdeps/powerpc/powerpc64/power7/memchr.S @@ -26,7 +26,17 @@ ENTRY (__memchr) dcbt 0,r3 clrrdi r8,r3,3 insrdi r4,r4,8,48 - add r7,r3,r5 /* Calculate the last acceptable address. */ + + /* Calculate the last acceptable address and check for possible + addition overflow by using satured math: + r7 = r3 + r5 + r7 |= -(r7 < x) */ + add r7,r3,r5 + subfc r6,r3,r7 + subfe r9,r9,r9 + extsw r6,r9 + or r7,r7,r6 + insrdi r4,r4,16,32 cmpldi r5,32 li r9, -1