{"id":2215801,"url":"http://patchwork.ozlabs.org/api/patches/2215801/?format=json","web_url":"http://patchwork.ozlabs.org/project/glibc/patch/20260325105900.828958-1-yury.khrustalev@arm.com/","project":{"id":41,"url":"http://patchwork.ozlabs.org/api/projects/41/?format=json","name":"GNU C Library","link_name":"glibc","list_id":"libc-alpha.sourceware.org","list_email":"libc-alpha@sourceware.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<20260325105900.828958-1-yury.khrustalev@arm.com>","list_archive_url":null,"date":"2026-03-25T10:59:00","name":"support: add __address_diff function","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"214eb44875094e34ea0048a61217630edbf3ef33","submitter":{"id":88214,"url":"http://patchwork.ozlabs.org/api/people/88214/?format=json","name":"Yury Khrustalev","email":"yury.khrustalev@arm.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/glibc/patch/20260325105900.828958-1-yury.khrustalev@arm.com/mbox/","series":[{"id":497417,"url":"http://patchwork.ozlabs.org/api/series/497417/?format=json","web_url":"http://patchwork.ozlabs.org/project/glibc/list/?series=497417","date":"2026-03-25T10:59:00","name":"support: add __address_diff function","version":1,"mbox":"http://patchwork.ozlabs.org/series/497417/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2215801/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2215801/checks/","tags":{},"related":[],"headers":{"Return-Path":"<libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org>","X-Original-To":["incoming@patchwork.ozlabs.org","libc-alpha@sourceware.org"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","libc-alpha@sourceware.org"],"Authentication-Results":["legolas.ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256\n header.s=foss header.b=fsuBHlyb;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=sourceware.org\n (client-ip=2620:52:6:3111::32; helo=vm01.sourceware.org;\n envelope-from=libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org;\n receiver=patchwork.ozlabs.org)","sourceware.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key,\n unprotected) header.d=arm.com header.i=@arm.com header.a=rsa-sha256\n header.s=foss header.b=fsuBHlyb","sourceware.org;\n dmarc=pass (p=none dis=none) header.from=arm.com","sourceware.org; spf=pass smtp.mailfrom=arm.com","server2.sourceware.org;\n arc=none smtp.remote-ip=217.140.110.172"],"Received":["from vm01.sourceware.org (vm01.sourceware.org\n [IPv6:2620:52:6:3111::32])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fgkSd1BLXz1xy3\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 25 Mar 2026 21:59:37 +1100 (AEDT)","from vm01.sourceware.org (localhost [127.0.0.1])\n\tby sourceware.org (Postfix) with ESMTP id 488994BB5920\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 25 Mar 2026 10:59:33 +0000 (GMT)","from foss.arm.com (foss.arm.com [217.140.110.172])\n by sourceware.org (Postfix) with ESMTP id 733B84BB5892\n for <libc-alpha@sourceware.org>; Wed, 25 Mar 2026 10:59:08 +0000 (GMT)","from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14])\n by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D543B16F2;\n Wed, 25 Mar 2026 03:59:01 -0700 (PDT)","from fdebian.localdomain (unknown [10.57.60.97])\n by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 2417E3FE53;\n Wed, 25 Mar 2026 03:59:07 -0700 (PDT)"],"DKIM-Filter":["OpenDKIM Filter v2.11.0 sourceware.org 488994BB5920","OpenDKIM Filter v2.11.0 sourceware.org 733B84BB5892"],"DMARC-Filter":"OpenDMARC Filter v1.4.2 sourceware.org 733B84BB5892","ARC-Filter":"OpenARC Filter v1.0.0 sourceware.org 733B84BB5892","ARC-Seal":"i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1774436348; cv=none;\n b=bZpky/ZbkXkOPaUHSpFBsxEJLco1hVhYl5HpmRkxGuJlzaC+xDr610SpUs0m/ATcAOYzh7JmigP/zXKns72xDG1K090Qgz5QJybY4do8HQOt7+jEEuDzk0Q1BLRWdVJcSJKcXEParHRb2FdAv+evBCRSEJ+YO4cbdkFk9LxSj0w=","ARC-Message-Signature":"i=1; a=rsa-sha256; d=sourceware.org; s=key;\n t=1774436348; c=relaxed/simple;\n bh=8or0qDdNR8r6ijjzOeS1YxPDhJJJv6nYp9uBS+Yneh4=;\n h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version;\n b=rG/xm+dTt6qwck731VAAAw00azt1RcQQvuQKr/DY2BNf0tIYnwEmqGSVNM+nWZ8+9s2ICPZORuc/A7kUXQhXUahiBjybL8Y8ff9MYHbbMK3zkSIo5DwOH/B1m210Fcn8tke4sE7hv4LXq/u4k4c4jbERpsqyXcymPAxUgi+adtg=","ARC-Authentication-Results":"i=1; server2.sourceware.org","DKIM-Signature":"v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss;\n t=1774436347; bh=8or0qDdNR8r6ijjzOeS1YxPDhJJJv6nYp9uBS+Yneh4=;\n h=From:To:Cc:Subject:Date:From;\n b=fsuBHlybKkoVU8bTFCP+i1uDmEnFKbQQvO+9gH/e1ps58ADisa8JNGcrnnl4YCc6X\n 371k07wYtGxlIm+PJrKnVHtsba0p6G3PL64zcAGACNRGM9taY+0c1BitYXOJd2NQm7\n 0HsZKarJ48iGGHtc/9T7eZ6L9wJbFadYx5yCz4tA=","From":"Yury Khrustalev <yury.khrustalev@arm.com>","To":"libc-alpha@sourceware.org","Cc":"Adhemerval Zanella <adhemerval.zanella@linaro.org>,\n Florian Weimer <fweimer@redhat.com>,\n Wilco Dijkstra <wilco.dijkstra@arm.com>","Subject":"[PATCH] support: add __address_diff function","Date":"Wed, 25 Mar 2026 10:59:00 +0000","Message-ID":"<20260325105900.828958-1-yury.khrustalev@arm.com>","X-Mailer":"git-send-email 2.47.3","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","X-BeenThere":"libc-alpha@sourceware.org","X-Mailman-Version":"2.1.30","Precedence":"list","List-Id":"Libc-alpha mailing list <libc-alpha.sourceware.org>","List-Unsubscribe":"<https://sourceware.org/mailman/options/libc-alpha>,\n <mailto:libc-alpha-request@sourceware.org?subject=unsubscribe>","List-Archive":"<https://sourceware.org/pipermail/libc-alpha/>","List-Post":"<mailto:libc-alpha@sourceware.org>","List-Help":"<mailto:libc-alpha-request@sourceware.org?subject=help>","List-Subscribe":"<https://sourceware.org/mailman/listinfo/libc-alpha>,\n <mailto:libc-alpha-request@sourceware.org?subject=subscribe>","Errors-To":"libc-alpha-bounces~incoming=patchwork.ozlabs.org@sourceware.org"},"content":"Some malloc tests compare pointers meaning to compare addresses.\nOn AArch64, the 64-bit value of the pointer may contain metadata\nalong with the values of the address.\n\nIn order to correctly compare addresses, we add new function for\nAArch64 target that will use the AArch64 64 SUBP (subtract pointer)\ninstruction when it is available. This instruction uses the 56-bit\naddresses ignoring top-byte metadata.\n\nBest implementation is selected using ifunc resolver.\n\nOn other targets and also on AArch64 when MTE is not available this\nfunction defaults to PTR_DIFF defined in libc-pointer-arith.h.\n\nThree malloc tests are modified accordingly:\n - tst-memalign-2.c\n - tst-memalign-3.c\n - tst-realloc.c\n\n---\nbase-commit: 4a97c12302\npasses regression on aarch64 and x86-64\n\nthere is probably a better way to add target-specific code\nto the support library?\n\n---\n malloc/tst-memalign-2.c         | 10 +++---\n malloc/tst-memalign-3.c         | 10 +++---\n malloc/tst-realloc.c            |  5 +--\n support/Makefile                |  1 +\n support/pointer-arith.h         | 31 +++++++++++++++++++\n support/support_pointer_arith.c | 55 +++++++++++++++++++++++++++++++++\n 6 files changed, 100 insertions(+), 12 deletions(-)\n create mode 100644 support/pointer-arith.h\n create mode 100644 support/support_pointer_arith.c","diff":"diff --git a/malloc/tst-memalign-2.c b/malloc/tst-memalign-2.c\nindex b3e393c249..c402f2c356 100644\n--- a/malloc/tst-memalign-2.c\n+++ b/malloc/tst-memalign-2.c\n@@ -22,7 +22,7 @@\n #include <string.h>\n #include <unistd.h>\n #include <array_length.h>\n-#include <libc-pointer-arith.h>\n+#include <support/pointer-arith.h>\n #include <support/check.h>\n #include \"tst-malloc-aux.h\"\n \n@@ -82,9 +82,9 @@ do_test (void)\n       /* This should return the same chunk as was just free'd.  */\n       tcache_allocs[i].ptr2 = memalign (tcache_allocs[i].alignment, sz2);\n       CHECK (tcache_allocs[i].ptr2, tcache_allocs[i].alignment);\n+      TEST_VERIFY (\n+\t  __address_diff (tcache_allocs[i].ptr1, tcache_allocs[i].ptr2) == 0);\n       free (tcache_allocs[i].ptr2);\n-\n-      TEST_VERIFY (tcache_allocs[i].ptr1 == tcache_allocs[i].ptr2);\n     }\n \n   /* Test for non-head tcache hits.  This exercises the memalign\n@@ -110,7 +110,7 @@ do_test (void)\n \n   count = 0;\n   for (i = 0; i < 10; ++ i)\n-    if (ptr[i] == p)\n+    if (__address_diff (ptr[i], p) == 0)\n       ++ count;\n   free (p);\n   TEST_VERIFY (count > 0);\n@@ -146,7 +146,7 @@ do_test (void)\n     {\n       int ok = 0;\n       for (j = 0; j < LN; ++ j)\n-\tif (large_allocs[i].ptr1 == large_allocs[j].ptr2)\n+\tif (__address_diff (large_allocs[i].ptr1, large_allocs[j].ptr2) == 0)\n \t  ok = 1;\n       if (ok == 1)\n \tcount ++;\ndiff --git a/malloc/tst-memalign-3.c b/malloc/tst-memalign-3.c\nindex 435e1c94d5..81756d265f 100644\n--- a/malloc/tst-memalign-3.c\n+++ b/malloc/tst-memalign-3.c\n@@ -23,7 +23,7 @@\n #include <string.h>\n #include <unistd.h>\n #include <array_length.h>\n-#include <libc-pointer-arith.h>\n+#include <support/pointer-arith.h>\n #include <support/check.h>\n #include <support/xthread.h>\n #include \"tst-malloc-aux.h\"\n@@ -85,9 +85,9 @@ mem_test (void *closure)\n       /* This should return the same chunk as was just free'd.  */\n       tcache_allocs[i].ptr2 = memalign (tcache_allocs[i].alignment, sz2);\n       CHECK (tcache_allocs[i].ptr2, tcache_allocs[i].alignment);\n+      TEST_VERIFY (\n+\t  __address_diff (tcache_allocs[i].ptr1, tcache_allocs[i].ptr2) == 0);\n       free (tcache_allocs[i].ptr2);\n-\n-      TEST_VERIFY (tcache_allocs[i].ptr1 == tcache_allocs[i].ptr2);\n     }\n \n   /* Test for non-head tcache hits.  */\n@@ -112,7 +112,7 @@ mem_test (void *closure)\n \n   count = 0;\n   for (i = 0; i < 10; ++ i)\n-    if (ptr[i] == p)\n+    if (__address_diff (ptr[i], p) == 0)\n       ++ count;\n   free (p);\n   TEST_VERIFY (count > 0);\n@@ -146,7 +146,7 @@ mem_test (void *closure)\n     {\n       int ok = 0;\n       for (j = 0; j < LN; ++ j)\n-\tif (large_allocs[i].ptr1 == large_allocs[j].ptr2)\n+\tif (__address_diff (large_allocs[i].ptr1, large_allocs[j].ptr2) == 0)\n \t  ok = 1;\n       if (ok == 1)\n \tcount ++;\ndiff --git a/malloc/tst-realloc.c b/malloc/tst-realloc.c\nindex e02b28d982..b5a0017b21 100644\n--- a/malloc/tst-realloc.c\n+++ b/malloc/tst-realloc.c\n@@ -22,6 +22,7 @@\n #include <string.h>\n #include <libc-diag.h>\n #include <support/check.h>\n+#include <support/pointer-arith.h>\n \n #include \"tst-malloc-aux.h\"\n \n@@ -155,9 +156,9 @@ do_test (void)\n       size_t newsz = malloc_usable_size (p);\n       printf (\"size: %zu, usable size: %zu, extra: %zu\\n\",\n \t      sz, newsz, newsz - sz);\n-      uintptr_t oldp = (uintptr_t) p;\n+      void *oldp = p;\n       void *new_p = realloc (p, newsz);\n-      if ((uintptr_t) new_p != oldp)\n+      if (__address_diff (new_p, oldp) != 0)\n \tFAIL_EXIT1 (\"Expanding (%zu bytes) to usable size (%zu) moved block\",\n \t\t    sz, newsz);\n       free (new_p);\ndiff --git a/support/Makefile b/support/Makefile\nindex 1dae2802cf..67990fe075 100644\n--- a/support/Makefile\n+++ b/support/Makefile\n@@ -94,6 +94,7 @@ libsupport-routines = \\\n   support_openpty \\\n   support_path_support_time64 \\\n   support_paths \\\n+  support_pointer_arith \\\n   support_process_state \\\n   support_ptrace \\\n   support_quote_blob \\\ndiff --git a/support/pointer-arith.h b/support/pointer-arith.h\nnew file mode 100644\nindex 0000000000..fc9cf593ac\n--- /dev/null\n+++ b/support/pointer-arith.h\n@@ -0,0 +1,31 @@\n+/* Support functions for pointer arithmetic.\n+   Copyright (C) 2026 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <https://www.gnu.org/licenses/>.  */\n+\n+#ifndef _POINTER_ARITH_H\n+#define _POINTER_ARITH_H 1\n+\n+#include <stddef.h>\n+#include <libc-pointer-arith.h>\n+\n+#ifdef __ARM_ARCH_ISA_A64\n+ptrdiff_t __address_diff (const void *lhs, const void *rhs);\n+#else\n+#define __address_diff PTR_DIFF\n+#endif /* __ARM_ARCH_ISA_A64 */\n+\n+#endif\ndiff --git a/support/support_pointer_arith.c b/support/support_pointer_arith.c\nnew file mode 100644\nindex 0000000000..56217aa821\n--- /dev/null\n+++ b/support/support_pointer_arith.c\n@@ -0,0 +1,55 @@\n+/* Support functions for pointer arithmetic.\n+   Copyright (C) 2026 Free Software Foundation, Inc.\n+   This file is part of the GNU C Library.\n+\n+   The GNU C Library is free software; you can redistribute it and/or\n+   modify it under the terms of the GNU Lesser General Public\n+   License as published by the Free Software Foundation; either\n+   version 2.1 of the License, or (at your option) any later version.\n+\n+   The GNU C Library is distributed in the hope that it will be useful,\n+   but WITHOUT ANY WARRANTY; without even the implied warranty of\n+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+   Lesser General Public License for more details.\n+\n+   You should have received a copy of the GNU Lesser General Public\n+   License along with the GNU C Library; if not, see\n+   <https://www.gnu.org/licenses/>.  */\n+\n+#ifdef __ARM_ARCH_ISA_A64\n+\n+#include \"pointer-arith.h\"\n+\n+#include <sys/ifunc.h>\n+#include <sys/auxv.h>\n+\n+static ptrdiff_t\n+__address_diff_mte (const void *lhs, const void *rhs)\n+{\n+  register const void *x0 asm (\"x0\") = lhs;\n+  register const void *x1 asm (\"x1\") = rhs;\n+  asm (\".inst 0x9ac10000 /* subp x0, x0, x1 */\" : \"+r\" (x0) : \"r\" (x1));\n+  return (ptrdiff_t)x0;\n+}\n+\n+static ptrdiff_t\n+__address_diff_generic (const void *lhs, const void *rhs)\n+{\n+  return PTR_DIFF (lhs, rhs);\n+}\n+\n+static void * __attribute__ ((unused))\n+__address_diff_resolver (unsigned long a0, const unsigned long *a1)\n+{\n+  unsigned long hwcap2 = __ifunc_hwcap (_IFUNC_ARG_AT_HWCAP2, a0, a1);\n+  if (hwcap2 & HWCAP2_MTE)\n+    return (void *)__address_diff_mte;\n+  return (void *)__address_diff_generic;\n+}\n+\n+\n+ptrdiff_t\n+__address_diff (const void *lhs, const void *rhs)\n+__attribute__ ((ifunc (\"__address_diff_resolver\")));\n+\n+#endif /* __ARM_ARCH_ISA_A64 */\n","prefixes":[]}