From patchwork Fri Sep 24 16:53:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 45425 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 08CC73858022 for ; Fri, 24 Sep 2021 16:54:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 08CC73858022 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1632502494; bh=eqL6m6tHaaElbiBmCsiOB1eUIks5ka86jkilky5Dx6c=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=Pew2PMf5shmc6dKuyFbcTomehngz6foWQeYYmKsyc+k0wGrH5VtFfkPfTHs4jH714 Rx+ZLz0mQM7w1z1/T0fuCm6wEZgrWw11Af6bmYlcbOFkTM41uoGlNAWW2m/AdaeyK6 37Dov67cuVVpxzYwys6a5haTMPwojDkpWPzzslM4= X-Original-To: libc-alpha@sourceware.org Delivered-To: libc-alpha@sourceware.org Received: from mail-pj1-x102b.google.com (mail-pj1-x102b.google.com [IPv6:2607:f8b0:4864:20::102b]) by sourceware.org (Postfix) with ESMTPS id BA1C13858402 for ; Fri, 24 Sep 2021 16:53:50 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org BA1C13858402 Received: by mail-pj1-x102b.google.com with SMTP id pf3-20020a17090b1d8300b0019e081aa87bso8019125pjb.0 for ; Fri, 24 Sep 2021 09:53:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eqL6m6tHaaElbiBmCsiOB1eUIks5ka86jkilky5Dx6c=; b=fDjqwLPDV1VJKazPUSINZB2FVXVvFB/ftNfv6z57WP2yAqeB7NlmATwb6PXsHEiO7w bdLPRe0I+lyTZ924i0ACPpRegpEjevbKKSX0j45Ql6jUZZldY/wG/ZvmKG3WJyHc17nV zHUKUTTjhacaVMv2Z5bT4n6afEIzdcz0ZLKj0uKxTn8VTxaxf8L70062y8t8oTCyRl71 +3TLv45vwMrDG3ZylJa4Y85eLsgpVmDI8iRjzBifpufqWGql7WcBGdV+llUw9+9ihkvB WkQKMlYJxGX+oGkkYyw2vMyYqa/AphgHTR/FuhBY7UopwDs6iJYDb4DQ8NXlrwvxZlYC jQeg== X-Gm-Message-State: AOAM531Cw9qpbqvzLpPt3P39cWR9VX2A9hZJXA5EsQzm2djClXbL3Sts SjwB09WZvpdsnTQ4yG6jWMQ= X-Google-Smtp-Source: ABdhPJw8S6v5OACPxPLlKRaYKupExvpT40Tt4sSxQUi+pUFHp3xTN/Gtx2LzkrNxSRhEv9xkIwKyqg== X-Received: by 2002:a17:902:c204:b0:13d:c6ef:7cf2 with SMTP id 4-20020a170902c20400b0013dc6ef7cf2mr10254492pll.33.1632502429104; Fri, 24 Sep 2021 09:53:49 -0700 (PDT) Received: from gnu-gram-1.localdomain (cpe-76-173-15-247.hawaii.res.rr.com. [76.173.15.247]) by smtp.gmail.com with ESMTPSA id s69sm10147129pgc.35.2021.09.24.09.53.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Sep 2021 09:53:48 -0700 (PDT) Received: from gnu-gram-1.localdomain (localhost [IPv6:::1]) by gnu-gram-1.localdomain (Postfix) with ESMTP id 9D531E0073; Fri, 24 Sep 2021 09:53:45 -0700 (PDT) To: libc-alpha@sourceware.org Subject: [PATCH v7 1/1] : An API for tagged address Date: Fri, 24 Sep 2021 09:53:38 -0700 Message-Id: <20210924165338.2326917-2-hjl.tools@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210924165338.2326917-1-hjl.tools@gmail.com> References: <20210924165338.2326917-1-hjl.tools@gmail.com> MIME-Version: 1.0 X-Spam-Status: No, score=-3032.2 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: libc-alpha@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Libc-alpha mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: "H.J. Lu via Libc-alpha" From: "H.J. Lu" Reply-To: "H.J. Lu" Cc: Florian Weimer , Szabolcs Nagy , Joseph Myers , "Kirill A . Shutemov" Errors-To: libc-alpha-bounces+patchwork=sourceware.org@sourceware.org Sender: "Libc-alpha" By default, the number of the address bits used in address translation is the number of address bits. But it can be changed by ARM Top-byte Ignore (TBI) or Intel Linear Address Masking (LAM). provides an API for tagged address manipulation with restrictions: 1. All bits between 0 and N - 1, where N is the number of tagged address bits, are used in address translation. 2. All pointers participating in a pointer arithmetic operation should have the same tag if they point to the same memory object so that pointer equality operation can be performed on tagged pointers. /* Set the mask for address bits used in address translation. Return 0 on success. Return -1 on error. */ extern int set_translated_address_mask (uintptr_t __mask); /* Non-zero if constant address BITS is a valid tagged address bits. */ #define TRANSLATED_ADDRESS_VALID_BITS(BITS) /* A mask for constant address BITS used in address translation. */ #define TRANSLATED_ADDRESS_MASK(BITS) 1. set_translated_address_mask should be called as early as possible. 2. set_translated_address_mask shouldn't be allowed after main or thread creation. 3. After set_translated_address_mask is called, don't allow it to be called again to change the tagged address mask. Otherwise, the previously tagged addresses may not work anymore. --- NEWS | 2 + bits/tagged-address-mask.h | 47 +++++++++++++++++++++ bits/tagged-address-valid-bits.h | 28 +++++++++++++ csu/libc-start.c | 3 ++ elf/dl-support.c | 5 +++ include/sys/tagged-address.h | 19 +++++++++ manual/Makefile | 3 +- manual/ctype.texi | 2 +- manual/memory.texi | 2 +- manual/tagged-address.texi | 48 +++++++++++++++++++++ misc/Makefile | 48 ++++++++++++++++++--- misc/set-translated-address-mask.c | 49 ++++++++++++++++++++++ misc/sys/tagged-address.h | 33 +++++++++++++++ misc/tagged-address.c | 50 ++++++++++++++++++++++ misc/tst-tagged-address-1-static.c | 1 + misc/tst-tagged-address-1.c | 55 +++++++++++++++++++++++++ misc/tst-tagged-address-2-static.c | 1 + misc/tst-tagged-address-2.c | 45 ++++++++++++++++++++ misc/tst-tagged-address-3-static.c | 1 + misc/tst-tagged-address-3.c | 48 +++++++++++++++++++++ misc/tst-tagged-address-4-static.c | 1 + misc/tst-tagged-address-4.c | 36 ++++++++++++++++ misc/tst-tagged-address-5.c | 25 +++++++++++ misc/tst-tagged-address-6.c | 34 +++++++++++++++ misc/tst-tagged-address-7.c | 41 ++++++++++++++++++ misc/tst-tagged-address-mod-5.c | 47 +++++++++++++++++++++ misc/tst-tagged-address-mod-6.c | 34 +++++++++++++++ misc/tst-tagged-address-mod-7.c | 35 ++++++++++++++++ sysdeps/generic/inline-tagged-address.h | 43 +++++++++++++++++++ sysdeps/generic/ldsodefs.h | 4 ++ 30 files changed, 782 insertions(+), 8 deletions(-) create mode 100644 bits/tagged-address-mask.h create mode 100644 bits/tagged-address-valid-bits.h create mode 100644 include/sys/tagged-address.h create mode 100644 manual/tagged-address.texi create mode 100644 misc/set-translated-address-mask.c create mode 100644 misc/sys/tagged-address.h create mode 100644 misc/tagged-address.c create mode 100644 misc/tst-tagged-address-1-static.c create mode 100644 misc/tst-tagged-address-1.c create mode 100644 misc/tst-tagged-address-2-static.c create mode 100644 misc/tst-tagged-address-2.c create mode 100644 misc/tst-tagged-address-3-static.c create mode 100644 misc/tst-tagged-address-3.c create mode 100644 misc/tst-tagged-address-4-static.c create mode 100644 misc/tst-tagged-address-4.c create mode 100644 misc/tst-tagged-address-5.c create mode 100644 misc/tst-tagged-address-6.c create mode 100644 misc/tst-tagged-address-7.c create mode 100644 misc/tst-tagged-address-mod-5.c create mode 100644 misc/tst-tagged-address-mod-6.c create mode 100644 misc/tst-tagged-address-mod-7.c create mode 100644 sysdeps/generic/inline-tagged-address.h diff --git a/NEWS b/NEWS index 889578bf39..b46de848db 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,8 @@ Version 2.35 Major new features: +* Add to provide an API for tagged address. + * Bump r_version in the debugger interface to 2 and add a new field, r_next, support multiple namespaces. diff --git a/bits/tagged-address-mask.h b/bits/tagged-address-mask.h new file mode 100644 index 0000000000..8762921083 --- /dev/null +++ b/bits/tagged-address-mask.h @@ -0,0 +1,47 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _BITS_TAGGED_ADDRESS_MASK_H +#define _BITS_TAGGED_ADDRESS_MASK_H 1 + +#ifndef _SYS_TAGGED_ADDRESS_H +# error "Never include this file directly. Use instead" +#endif + +#include + +#ifdef __cplusplus +# if __cplusplus >= 201103L +# define TRANSLATED_ADDRESS_ASSERT static_assert +# else +# define TRANSLATED_ADDRESS_ASSERT(expr, msg) +# endif +#else +# define TRANSLATED_ADDRESS_ASSERT _Static_assert +#endif + +/* A mask for constant address BITS used in address translation. */ +#define TRANSLATED_ADDRESS_MASK(BITS) \ + (__extension__ \ + ({ \ + TRANSLATED_ADDRESS_ASSERT \ + (TRANSLATED_ADDRESS_VALID_BITS (BITS), \ + "Translated address bits must be valid"); \ + (((uintptr_t) 1) << (BITS)) - 1; \ + })) + +#endif /* */ diff --git a/bits/tagged-address-valid-bits.h b/bits/tagged-address-valid-bits.h new file mode 100644 index 0000000000..995bc2899b --- /dev/null +++ b/bits/tagged-address-valid-bits.h @@ -0,0 +1,28 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _BITS_TAGGED_ADDRESS_VALID_BITS_H +#define _BITS_TAGGED_ADDRESS_VALID_BITS_H 1 + +#ifndef _SYS_TAGGED_ADDRESS_H +# error "Never include this file directly. Use instead" +#endif + +/* Non-zero if constant address BITS is a valid translated address bits. */ +#define TRANSLATED_ADDRESS_VALID_BITS(BITS) 0 + +#endif /* */ diff --git a/csu/libc-start.c b/csu/libc-start.c index 0350b006fd..6f8ffa08f0 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -402,6 +402,9 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), GLRO(dl_debug_printf) ("\ntransferring control: %s\n\n", argv[0]); #endif + /* set_translated_address_mask can only be called before main. */ + GL(dl_translated_address_mask_locked) = 1; + #ifndef SHARED _dl_debug_initialize (0, LM_ID_BASE); #endif diff --git a/elf/dl-support.c b/elf/dl-support.c index 02e2ed72f5..784fb6a58d 100644 --- a/elf/dl-support.c +++ b/elf/dl-support.c @@ -212,6 +212,11 @@ struct link_map *_dl_sysinfo_map; # include "get-dynamic-info.h" #endif + +/* If nonzero, the mask for address bits used in address translation + is locked. */ +int _dl_translated_address_mask_locked; + #include "setup-vdso.h" /* Define the vDSO function pointers. */ #include diff --git a/include/sys/tagged-address.h b/include/sys/tagged-address.h new file mode 100644 index 0000000000..4f94dab511 --- /dev/null +++ b/include/sys/tagged-address.h @@ -0,0 +1,19 @@ +#include + +#ifdef _ISOMAC +/* Get the current address bits used in address translation. */ +extern unsigned int __libc_get_translated_address_bits (void); + +/* Get the current mask for address bits used in address translation. */ +extern uintptr_t __libc_get_translated_address_mask (void); + +/* Return the tagged address of __ADDR with the tag value __TAG. */ +extern void *__libc_tag_address (const void *__addr, + unsigned int __tag); + +/* Return the untagged address of __ADDR. */ +extern void *__libc_untag_address (const void *__addr); + +#else +# include +#endif diff --git a/manual/Makefile b/manual/Makefile index e83444341e..08df2daa6b 100644 --- a/manual/Makefile +++ b/manual/Makefile @@ -34,7 +34,8 @@ info: $(objpfx)libc.info endif chapters = $(addsuffix .texi, \ - intro errno memory ctype string charset locale \ + intro errno memory tagged-address ctype string \ + charset locale \ message search pattern io stdio llio filesys \ pipe socket terminal syslog math arith time \ resource setjmp signal startup process ipc job \ diff --git a/manual/ctype.texi b/manual/ctype.texi index d0618c5c38..28af73ff0e 100644 --- a/manual/ctype.texi +++ b/manual/ctype.texi @@ -1,4 +1,4 @@ -@node Character Handling, String and Array Utilities, Memory, Top +@node Character Handling, String and Array Utilities, Tagged Address, Top @c %MENU% Character testing and conversion functions @chapter Character Handling diff --git a/manual/memory.texi b/manual/memory.texi index 0b2b9c8795..2e283e41f9 100644 --- a/manual/memory.texi +++ b/manual/memory.texi @@ -1,4 +1,4 @@ -@node Memory, Character Handling, Error Reporting, Top +@node Memory, Tagged Address, Error Reporting, Top @chapter Virtual Memory Allocation And Paging @c %MENU% Allocating virtual memory and controlling paging @cindex memory allocation diff --git a/manual/tagged-address.texi b/manual/tagged-address.texi new file mode 100644 index 0000000000..d10e67b7e2 --- /dev/null +++ b/manual/tagged-address.texi @@ -0,0 +1,48 @@ +@node Tagged Address, Character Handling, Memory, Top +@c %MENU% Tagged address functions and macros +@chapter Tagged Address + +By default, the number of the address bits used in address translation +is the number of address bits. But it can be changed by ARM Top-byte +Ignore (TBI) or Intel Linear Address Masking (LAM). + +@Theglibc{} provides one function and two macros in the header file +@file{sys/tagged-address.h} to manipulate translated address bits, +which is the number of the address bits used in address translation, +with restrictions: + +@itemize @bullet +@item +All bits between 0 and N - 1, where N is the number of translated address +bits, are used in address translation. + +@item +All pointers participating in a pointer arithmetic operation should have +the same tag if they point to the same memory object so that pointer +equality operation can be performed on tagged pointers. +@end itemize + +@pindex sys/tagged-address.h + +@deftypefun int set_translated_address_mask (uintptr_t @var{mask}) +@standards{GNU, sys/tagged-address.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +Set the mask for address bits used in address translation to @var{mask}. +Only bits set in @var{mask} will be used in address translation. The +return value is @code{0} on success and @code{-1} on failure. This +function can be called only once before @code{main} and thread creation. +The possible @code{errno} error conditions are @code{ENODEV}, @code{EPERM}, +@code{EINVAL}, and @code{ENOSYS}. +@end deftypefun + +@deftypefn Macro int TRANSLATED_ADDRESS_VALID_BITS (@var{bits}) +This macro returns a nonzero value (true) if @var{bits} is a valid +constant number of the lower address bits which can be used in address +translation. +@end deftypefn + +@deftypefn Macro {const uintptr_t} TRANSLATED_ADDRESS_MASK (@var{bits}) +This macro returns a nonzero value which can be passed to +@code{set_translated_address_mask} to specify the lower address +@var{bits} for address translation. +@end deftypefn diff --git a/misc/Makefile b/misc/Makefile index 1083ba3bfc..82555c7dc1 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -38,7 +38,10 @@ headers := sys/uio.h bits/uio-ext.h bits/uio_lim.h \ bits/select2.h bits/hwcap.h sys/auxv.h \ sys/sysmacros.h bits/sysmacros.h bits/types/struct_iovec.h \ bits/err-ldbl.h bits/error-ldbl.h \ - sys/single_threaded.h + sys/single_threaded.h \ + sys/tagged-address.h \ + bits/tagged-address-mask.h \ + bits/tagged-address-valid-bits.h routines := brk sbrk sstk ioctl \ readv writev preadv preadv64 pwritev pwritev64 \ @@ -73,7 +76,12 @@ routines := brk sbrk sstk ioctl \ fgetxattr flistxattr fremovexattr fsetxattr getxattr \ listxattr lgetxattr llistxattr lremovexattr lsetxattr \ removexattr setxattr getauxval ifunc-impl-list makedev \ - allocate_once fd_to_filename single_threaded unwind-link + allocate_once fd_to_filename single_threaded unwind-link \ + tagged-address set-translated-address-mask + +# Put the initial in libc_nonshared.a for easy +# backport. +static-only-routines += tagged-address set-translated-address-mask generated += tst-error1.mtrace tst-error1-mem.out \ tst-allocate_once.mtrace tst-allocate_once-mem.out @@ -89,7 +97,11 @@ tests := tst-dirname tst-tsearch tst-fdset tst-mntent tst-hsearch \ tst-preadvwritev2 tst-preadvwritev64v2 tst-warn-wide \ tst-ldbl-warn tst-ldbl-error tst-dbl-efgcvt tst-ldbl-efgcvt \ tst-mntent-autofs tst-syscalls tst-mntent-escape tst-select \ - tst-ioctl + tst-ioctl \ + tst-tagged-address-1 tst-tagged-address-1-static \ + tst-tagged-address-2 tst-tagged-address-2-static \ + tst-tagged-address-3 tst-tagged-address-3-static \ + tst-tagged-address-4 tst-tagged-address-4-static tests-time64 := \ tst-select-time64 \ @@ -99,11 +111,24 @@ tests-time64 := \ # Tests which need libdl. ifeq (yes,$(build-shared)) -tests += tst-gethostid +tests += tst-gethostid \ + tst-tagged-address-5 \ + tst-tagged-address-6 \ + tst-tagged-address-7 +modules-names-tst-tagged-address = \ + tst-tagged-address-mod-5 \ + tst-tagged-address-mod-6 \ + tst-tagged-address-mod-7 +modules-names += $(modules-names-tst-tagged-address) +modules-names-tests += $(modules-names-tst-tagged-address) endif tests-internal := tst-atomic tst-atomic-long tst-allocate_once -tests-static := tst-empty +tests-static := tst-empty \ + tst-tagged-address-1-static \ + tst-tagged-address-2-static \ + tst-tagged-address-3-static \ + tst-tagged-address-4-static # Test for the internal, non-exported __fd_to_filename function. tests-internal += tst-fd_to_filename @@ -149,6 +174,10 @@ CFLAGS-sbrk.op = $(no-stack-protector) CFLAGS-brk.o = $(no-stack-protector) CFLAGS-brk.op = $(no-stack-protector) +# Compile set-translated-address-mask.oS in libc_nonshared.a with -DSHARED +# to use GL(dl_XXX) in ld.so, instead of _dl_XXX in libc.a. +CPPFLAGS-set-translated-address-mask.oS += -DSHARED + include ../Rules $(objpfx)libg.a: $(dep-dummy-lib); $(make-dummy-lib) @@ -172,3 +201,12 @@ $(objpfx)tst-select: $(librt) $(objpfx)tst-select-time64: $(librt) $(objpfx)tst-pselect: $(librt) $(objpfx)tst-pselect-time64: $(librt) + +$(objpfx)tst-tagged-address-2: $(shared-thread-library) +$(objpfx)tst-tagged-address-2-static: $(static-thread-library) +$(objpfx)tst-tagged-address-5: $(objpfx)tst-tagged-address-mod-5.so +$(objpfx)tst-tagged-address-mod-5.so: $(libsupport) +$(objpfx)tst-tagged-address-6: $(objpfx)tst-tagged-address-mod-6.so +$(objpfx)tst-tagged-address-mod-6.so: $(libsupport) +$(objpfx)tst-tagged-address-7.out: $(objpfx)tst-tagged-address-mod-7.so +$(objpfx)tst-tagged-address-mod-7.so: $(libsupport) diff --git a/misc/set-translated-address-mask.c b/misc/set-translated-address-mask.c new file mode 100644 index 0000000000..e29797a22e --- /dev/null +++ b/misc/set-translated-address-mask.c @@ -0,0 +1,49 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +#ifdef LIBC_NONSHARED +/* Use the global errno in libc_nonshared.a. */ +# undef errno +extern __thread int errno; +# undef __set_errno +# define __set_errno(n) errno = n +#endif + +/* Set the mask for address bits used in address translation. Return 0 + on success. Return -1 on error. */ + +int +set_translated_address_mask (uintptr_t mask) +{ + if (GL(dl_translated_address_mask_locked) != 0) + __set_errno (EPERM); + else + { + /* set_translated_address_mask can only be called once. */ + GL(dl_translated_address_mask_locked) = 1; + + /* Only NOP is allowed. */ + if (mask == __get_translated_address_mask ()) + return 0; + + __set_errno (ENOSYS); + } + return -1; +} diff --git a/misc/sys/tagged-address.h b/misc/sys/tagged-address.h new file mode 100644 index 0000000000..a0a91bad75 --- /dev/null +++ b/misc/sys/tagged-address.h @@ -0,0 +1,33 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#ifndef _SYS_TAGGED_ADDRESS_H +#define _SYS_TAGGED_ADDRESS_H 1 + +#include +#include +#include + +__BEGIN_DECLS + +/* Set the mask for address bits used in address translation. Return 0 + on success. Return -1 on error. */ +extern int set_translated_address_mask (uintptr_t __mask); + +__END_DECLS + +#endif /* */ diff --git a/misc/tagged-address.c b/misc/tagged-address.c new file mode 100644 index 0000000000..7c405facff --- /dev/null +++ b/misc/tagged-address.c @@ -0,0 +1,50 @@ +/* Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +/* Get the current address bits used in address translation. */ + +unsigned int +__libc_get_translated_address_bits (void) +{ + return __get_translated_address_bits (); +} + +/* Get the current mask for address bits used in address translation. */ + +uintptr_t +__libc_get_translated_address_mask (void) +{ + return __get_translated_address_mask (); +} + +/* Return the tagged address of ADDR with the tag value TAG. */ + +void * +__libc_tag_address (const void *addr, unsigned int tag) +{ + return __tag_address (addr, tag); +} + +/* Return the untagged address of ADDR. */ + +void * +__libc_untag_address (const void *addr) +{ + return __untag_address (addr); +} diff --git a/misc/tst-tagged-address-1-static.c b/misc/tst-tagged-address-1-static.c new file mode 100644 index 0000000000..3ed71a66c2 --- /dev/null +++ b/misc/tst-tagged-address-1-static.c @@ -0,0 +1 @@ +#include diff --git a/misc/tst-tagged-address-1.c b/misc/tst-tagged-address-1.c new file mode 100644 index 0000000000..0751be9b24 --- /dev/null +++ b/misc/tst-tagged-address-1.c @@ -0,0 +1,55 @@ +/* Tests for set_translated_address_mask before main. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +static void +init_0 (void) +{ + if (set_translated_address_mask (__libc_get_translated_address_mask ()) + != 0) + FAIL_EXIT1 ("set_translated_address_mask failed: %m"); +} + +static void +init_1 (void) +{ + if (set_translated_address_mask (__libc_get_translated_address_mask ()) + == 0) + FAIL_EXIT1 ("set_translated_address_mask should fail"); + + if (errno != EPERM) + FAIL_EXIT1 ("set_translated_address_mask: errno (%m) != EPERM"); +} + +static void (*init_array []) (void) + __attribute__ ((used, section (".init_array"), aligned (sizeof (void *)))) = +{ + &init_0, + &init_1 +}; + +static int +do_test (void) +{ + return 0; +} + +#include diff --git a/misc/tst-tagged-address-2-static.c b/misc/tst-tagged-address-2-static.c new file mode 100644 index 0000000000..ac0d95e6c0 --- /dev/null +++ b/misc/tst-tagged-address-2-static.c @@ -0,0 +1 @@ +#include diff --git a/misc/tst-tagged-address-2.c b/misc/tst-tagged-address-2.c new file mode 100644 index 0000000000..00a97148f8 --- /dev/null +++ b/misc/tst-tagged-address-2.c @@ -0,0 +1,45 @@ +/* Test for set_translated_address_mask before main with pthread. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include +#include + +static void * +tf (void *arg) +{ + if (set_translated_address_mask (__libc_get_translated_address_mask ()) + == 0) + FAIL_EXIT1 ("set_translated_address_mask should fail"); + + if (errno != EPERM) + FAIL_EXIT1 ("set_translated_address_mask: errno (%m) != EPERM"); + + return NULL; +} + +static int +do_test (void) +{ + pthread_t thr = xpthread_create (NULL, tf, NULL); + xpthread_join (thr); + return 0; +} + +#include diff --git a/misc/tst-tagged-address-3-static.c b/misc/tst-tagged-address-3-static.c new file mode 100644 index 0000000000..1e3591e0d6 --- /dev/null +++ b/misc/tst-tagged-address-3-static.c @@ -0,0 +1 @@ +#include diff --git a/misc/tst-tagged-address-3.c b/misc/tst-tagged-address-3.c new file mode 100644 index 0000000000..04d2f8d3da --- /dev/null +++ b/misc/tst-tagged-address-3.c @@ -0,0 +1,48 @@ +/* Tests for set_translated_address_mask to turn off tagged address. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +static void +init (void) +{ + uintptr_t mask = (uintptr_t) -1; + if (set_translated_address_mask (mask) != 0) + FAIL_EXIT1 ("set_translated_address_mask failed: %m"); +} + +static void (*init_array []) (void) + __attribute__ ((used, section (".init_array"), aligned (sizeof (void *)))) = +{ + &init +}; + +static int +do_test (void) +{ + uintptr_t mask = (uintptr_t) -1; + uintptr_t curent_mask = __libc_get_translated_address_mask (); + if (curent_mask != mask) + FAIL_EXIT1 ("get_translated_address_mask failed: %p != %p", + (void *) curent_mask, (void *) mask); + + return 0; +} + +#include diff --git a/misc/tst-tagged-address-4-static.c b/misc/tst-tagged-address-4-static.c new file mode 100644 index 0000000000..b0681f6f9b --- /dev/null +++ b/misc/tst-tagged-address-4-static.c @@ -0,0 +1 @@ +#include diff --git a/misc/tst-tagged-address-4.c b/misc/tst-tagged-address-4.c new file mode 100644 index 0000000000..9131373ba1 --- /dev/null +++ b/misc/tst-tagged-address-4.c @@ -0,0 +1,36 @@ +/* Test for set_translated_address_mask after main. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +static int +do_test (void) +{ + if (set_translated_address_mask (__libc_get_translated_address_mask ()) + == 0) + FAIL_EXIT1 ("set_translated_address_mask should fail"); + + if (errno != EPERM) + FAIL_EXIT1 ("set_translated_address_mask: errno (%m) != EPERM"); + + return 0; +} + +#include diff --git a/misc/tst-tagged-address-5.c b/misc/tst-tagged-address-5.c new file mode 100644 index 0000000000..f3c6ce5935 --- /dev/null +++ b/misc/tst-tagged-address-5.c @@ -0,0 +1,25 @@ +/* Tests for set_translated_address_mask in a shared library before main. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +static int +do_test (void) +{ + return 0; +} + +#include diff --git a/misc/tst-tagged-address-6.c b/misc/tst-tagged-address-6.c new file mode 100644 index 0000000000..60c6497af2 --- /dev/null +++ b/misc/tst-tagged-address-6.c @@ -0,0 +1,34 @@ +/* Tests for set_translated_address_mask to turn off tagged address. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +static int +do_test (void) +{ + uintptr_t mask = (uintptr_t) -1; + uintptr_t curent_mask = __libc_get_translated_address_mask (); + if (curent_mask != mask) + FAIL_EXIT1 ("get_translated_address_mask failed: %p != %p", + (void *) curent_mask, (void *) mask); + + return 0; +} + +#include diff --git a/misc/tst-tagged-address-7.c b/misc/tst-tagged-address-7.c new file mode 100644 index 0000000000..7d987e19e3 --- /dev/null +++ b/misc/tst-tagged-address-7.c @@ -0,0 +1,41 @@ +/* Test for set_translated_address_mask in a dlopened shared library + after main. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +static int +do_test (void) +{ + const char *modname = "$ORIGIN/tst-tagged-address-mod-7.so"; + void *h = dlopen (modname, RTLD_LAZY); + + if (h == NULL) + { + const char *err = dlerror (); + FAIL_EXIT1 ("cannot open '%s': %s\n", modname, err); + } + + dlclose (h); + + return 0; +} + +#include diff --git a/misc/tst-tagged-address-mod-5.c b/misc/tst-tagged-address-mod-5.c new file mode 100644 index 0000000000..88b8d6a261 --- /dev/null +++ b/misc/tst-tagged-address-mod-5.c @@ -0,0 +1,47 @@ +/* Tests for set_translated_address_mask in a shared library. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +static void +init_0 (void) +{ + if (set_translated_address_mask (__libc_get_translated_address_mask ()) + != 0) + FAIL_EXIT1 ("set_translated_address_mask failed: %m"); +} + +static void +init_1 (void) +{ + if (set_translated_address_mask (__libc_get_translated_address_mask ()) + == 0) + FAIL_EXIT1 ("set_translated_address_mask should fail"); + + if (errno != EPERM) + FAIL_EXIT1 ("set_translated_address_mask: errno (%m) != EPERM"); +} + +static void (*init_array []) (void) + __attribute__ ((used, section (".init_array"), aligned (sizeof (void *)))) = +{ + &init_0, + &init_1 +}; diff --git a/misc/tst-tagged-address-mod-6.c b/misc/tst-tagged-address-mod-6.c new file mode 100644 index 0000000000..4d9396425d --- /dev/null +++ b/misc/tst-tagged-address-mod-6.c @@ -0,0 +1,34 @@ +/* Tests for set_translated_address_mask to turn off tagged address. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +static void +init (void) +{ + uintptr_t mask = (uintptr_t) -1; + if (set_translated_address_mask (mask) != 0) + FAIL_EXIT1 ("set_translated_address_mask failed: %m"); +} + +static void (*init_array []) (void) + __attribute__ ((used, section (".init_array"), aligned (sizeof (void *)))) = +{ + &init +}; diff --git a/misc/tst-tagged-address-mod-7.c b/misc/tst-tagged-address-mod-7.c new file mode 100644 index 0000000000..7d8f80a232 --- /dev/null +++ b/misc/tst-tagged-address-mod-7.c @@ -0,0 +1,35 @@ +/* Tests for set_translated_address_mask to turn off tagged address in + a shared library. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include + +static void +init (void) +{ + uintptr_t mask = (uintptr_t) -1; + if (set_translated_address_mask (mask) == 0) + FAIL_EXIT1 ("set_translated_address_mask should have failed"); +} + +static void (*init_array []) (void) + __attribute__ ((used, section (".init_array"), aligned (sizeof (void *)))) = +{ + &init +}; diff --git a/sysdeps/generic/inline-tagged-address.h b/sysdeps/generic/inline-tagged-address.h new file mode 100644 index 0000000000..3b733e437b --- /dev/null +++ b/sysdeps/generic/inline-tagged-address.h @@ -0,0 +1,43 @@ +/* Inline tagged address functions. Generic version. + Copyright (C) 2021 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +static inline unsigned int +__get_translated_address_bits (void) +{ + return sizeof (uintptr_t) * 8; +} + +static inline uintptr_t +__get_translated_address_mask (void) +{ + return (uintptr_t) -1; +} + +static inline void * +__tag_address (const void *addr, unsigned int tag) +{ + return (void *) addr; +} + +static inline void * +__untag_address (const void *addr) +{ + return (void *) addr; +} diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index d49529da0d..e13e526bd8 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -492,6 +492,10 @@ struct rtld_global EXTERN struct __pthread **_dl_pthread_threads; __libc_rwlock_define (EXTERN, _dl_pthread_threads_lock) #endif + + /* If nonzero, the mask for address bits used in address translation + is locked. */ + EXTERN int _dl_translated_address_mask_locked; #ifdef SHARED }; # define __rtld_global_attribute__